Dive into collaborative coding, envisioning a seamless process where developers’ commits trigger automatic builds, tests, and deployments. Starting with a manual deployment of HTML code on a Nginx web server, we transition into the world of AWS CodePipeline, automating the CI/CD pipeline for our sample code. To add a twist, we deliberately introduce deployment errors, unraveling the power of AWS CodeDeploy’s rollback mechanism—effortlessly reverting to a previously successful deployment. Experience the simplicity and reliability of managing deployment complexities with AWS CodeDeploy.
Prerequisites for AWS DevOps Projects:
Before embarking on the project, it is essential to ensure that the following prerequisites are installed and configured:
1. AWS Account with Administrator Policy: Ensure you have an AWS account with the Administrator policy. Alternatively, you can assign specific permissions to the user. Generate HTTPS Git credentials for AWS CodeCommit, which will enable code push from a local source to a CodeCommit repository. To achieve this, navigate to IAM => Users => Security credentials => HTTPS Git credentials for AWS CodeCommit => Generate credentials.
2. EC2 Instance Setup: Deploy an EC2 instance with the following specifications: AMI – Ubuntu, Type – t2.micro, Region – us-east-1. You can install the CodeDeploy Agent by executing the provided script given below either during the EC2 instance creation or afterward. The outlined steps are specifically for Ubuntu AMI.
3. IAM Role Configuration: Attach an IAM role to your EC2 instance. Navigate to your running instance, click on Actions => Security => Modify IAM role => Create a new IAM role (if not already created) => Create role. Ensure the role has the necessary permissions, as illustrated below.
4. Security Group Configuration: Adjust the security group associated with your instance by adding two additional inbound ports: 443 and 80. Navigate to the Security tab of your EC2 instance => click on the Security group => go to the Inbound rules tab => click on edit => Add two ports (443 and 80) => Save.
5. CodeDeploy Agent Management: SSH into your instance, stop the agent, and restart it using the provided commands below:
Stopping the agent:
Starting the agent and checking the status:
Note: This blog provides a concise overview of AWS CodeCommit, CodeBuild, CodeDeploy, and CodePipeline. For an in-depth understanding of AWS DevOps, refer to another detailed blog linked here.
Understanding AWS CodeCommit:
AWS CodeCommit stands as a version control service offered by Amazon Web Services, dedicated to the confidential storage and management of diverse assets, including documents, source code, and binary files within the cloud.
Step 1: Create an AWS CodeCommit Repository
- ● Navigate to the AWS CodeCommit console and select “Create repository.”
- ● Provide a repository name, description, and specify its visibility (public or private).
- ● Click “Create” to instantiate the repository.
- ● After creation, obtain the repository’s clone URL for local machine access.
- ● Clone the repository locally using Git.
Develop sample files and scripts for CodeDeploy to enhance the efficiency of your AWS CodePipeline. While our blog focuses on a static web application with HTML, CSS, Bootstrap, and JS components, it is crucial to set up essential files:
Create Sample Files: Generate essential files like index.html, buildspec.yml, appspec.yml, and any necessary scripts tailored for CodeDeploy.
Write buildspec.yml file for code build & store artifacts in s3 Bucket.
This YAML file serves as a build specification for AWS CodeBuild, orchestrating the different stages of the build process for your application.
Version Specification:
The version: 0.2 at the top indicates the version of the buildspec file format being used.
Build Phases:
The phases section defines three stages executed sequentially during the build process: install, build, and post_build.
Install Phase:
Installs the NGINX web server by updating the package list and installing NGINX using the apt-get package manager.
Build Phase:
Initiates the build process, echoing a message with the current date and copying the index.html file to the /var/www/html/ directory on the build server, the default location for serving web content for NGINX.
Post-Build Phase:
Executes tasks after the build, echoing a message indicating the configuration of NGINX.
Artifact Specification:
The artifacts section specifies the files to be included in the output artifact produced by the build.
The files attribute, denoted by **/*, includes all files and directories in the build output directory recursively.
In summary, this buildspec.yml file outlines the necessary steps to install NGINX, initiate the build process, configure NGINX post-build, and defines the artifacts to be included in the output. It forms a crucial component of AWS CodeBuild, ensuring a streamlined and automated build, test, and deployment workflow for your application.
Add Script for installing & starting NGINX Webserver:
1. Create a folder named scripts & Write install_nginx.sh to install Nginx
This Bash script is designed to install and start the NGINX web server on an Ubuntu-based system. Let’s break down each part of the script:
Shebang Line:
#!/bin/bash: This line, known as the shebang, specifies that the script should be interpreted and executed using the Bash shell.
Update Package List:
sudo apt-get update: This command updates the package list on the Ubuntu system. It involves downloading the latest information about available software packages from the Ubuntu repositories. This step is essential to ensure that the system has access to the most recent software versions and security updates.
Install NGINX:
sudo apt-get install -y nginx: This command installs the NGINX web server on the system. The -y option automatically confirms any prompts that may appear during the installation process, making it a non-interactive installation. NGINX is a popular web server that is widely used for hosting websites and serving web content.
In summary, this Bash script serves as a straightforward automation tool for updating the package list and installing the NGINX web server on an Ubuntu-based system. It is a foundational component in the deployment process, ensuring that the necessary web server is installed and ready to serve web content.
2. write start_nginx.sh un scripts folder to start the Nginx webserver
This Bash script contains a single command to start the NGINX web server. Let’s break down each part of the script:
Start NGINX Service:
sudo service nginx start: This command initiates the NGINX web server by running the start command on the nginx service. The sudo command is used to execute the following command with elevated privileges.
Explanation:
- ● The service command is a system utility for managing services on Unix-like operating systems. In this case, it’s used to interact with the NGINX service.
- ● nginx is the name of the service being managed. NGINX is a popular web server and reverse proxy server.
- ● start is the action being performed on the NGINX service. It instructs the system to launch the NGINX process and begin serving web pages.
In summary, this Bash script serves as a simple command to start the NGINX web server. It is a crucial step in the deployment process, ensuring that the web server is activated and ready to handle web requests, making the hosted content accessible to users.
Write appspec.yml file for CodeDeploy
The file specifies the deployment steps and actions that CodeDeploy should take when deploying an application to a Linux instance.
Deployment Version and OS:
- ● version: 0.0: Specifies the version of the deployment specification file being used.
- ● os: linux: Specifies the target operating system for deployment, which is Linux in this case.
Files Section:
The files section specifies the files that should be copied to the instance during the deployment process.
- ● – source: /: Indicates the source directory in the application source.
- ● destination: /var/www/html: Specifies the destination directory on the target instance where the files from the source directory will be copied. In this case, it’s the default location for serving web content on Linux instances.
Hooks Section:
The hooks section specifies the lifecycle events that should trigger scripts to run on the target instance during the deployment process. In this case, there are two hooks:
1. AfterInstall Hook:
- ● location: scripts/install_nginx.sh: Specifies the location of the script to be executed after the files have been copied. In this case, it’s install_nginx.sh.
- ● timeout: 300: Sets the maximum time allowed for the script to complete (in seconds).
- ● runas: root: Indicates that the script will be executed with root privileges.
2. ApplicationStart Hook:
- ● location: scripts/start_nginx.sh: Specifies the location of the script to be executed after the NGINX server installation. In this case, it’s start_nginx.sh.
- ● timeout: 300: Sets the maximum time allowed for the script to complete (in seconds).
- ● runas: root: Indicates that the script will be executed with root privileges.
3. Git Commands Note:
- ● The final note indicates that after creating and saving all the files, they should be pushed to the CodeCommit repository using Git commands (git add, git commit, and git push).
- ● Also, a reminder that you’ll be prompted for the ID and password when pushing to CodeCommit.
In summary, this appspec.yml file defines the deployment process, specifying file copying and execution of scripts during the deployment lifecycle on a Linux instance using AWS CodeDeploy. The provided scripts install and start the NGINX web server on the target instance.
What is AWS CodeBuild?
AWS CodeBuild is a fully managed cloud-based build service designed to streamline the process of compiling source code, executing unit tests, and generating deployable artifacts. It is a versatile solution that eliminates the complexities of provisioning, managing, and scaling individual build servers. CodeBuild supports popular programming languages and build tools such as Apache Maven and Gradle, offering prepackaged build environments. Moreover, users can customize these environments to incorporate their preferred build tools. Notably, CodeBuild automatically scales to accommodate varying build demands, ensuring efficient resource utilization.
Key Benefits of AWS CodeBuild:
Fully Managed:
CodeBuild alleviates the burden of setting up, patching, updating, and managing individual build servers. It provides a hassle-free, fully managed build service.
On-Demand Scaling:
The service scales dynamically in response to changing build requirements. Users only pay for the actual build minutes consumed, optimizing cost efficiency.
Out-of-the-Box Convenience:
CodeBuild simplifies the initiation of builds by offering preconfigured environments for widely used programming languages. Users can swiftly commence their initial builds by specifying their build script.
Step 2: Create a CodeBuild Project:
- ● Go to the AWS CodeBuild console and initiate the process by clicking “Create build project.”
- ● Provide a meaningful name and description for your build project.
- ● In the “Source” section, select “AWS CodeCommit” as the source provider and choose the relevant repository from Step 1. Specify the desired branch.
- ● Under “Environment,” opt for a build environment that suits your requirements (e.g., “Ubuntu”) and choose the runtime as “Standard:6.0.”
- ● In the “Buildspec” section, choose “Use a buildspec file.”
- ● For the “Artifacts” section, designate “Amazon S3” as the artifact type. Specify the S3 bucket and key prefix where build artifacts will be stored. Choose “Zip” as the artifacts packaging.
- ● In the “Logs” section, uncheck the “CloudWatch logs” checkbox.
- ● Click “Create build project” to generate the CodeBuild project.
- ● Initiate the build process by clicking “Start Build.” Upon completion of all stages, the build file will be generated in the specified S3 Bucket.
AWS CodeBuild streamlines the build and deployment pipeline, offering a seamless and efficient experience for developers and teams.
What is CodeDeploy?
CodeDeploy serves as a robust deployment service designed to automate the process of deploying applications across diverse environments, encompassing Amazon EC2 instances, on-premises instances, serverless Lambda functions, and Amazon ECS services.
Key Features and Capabilities of CodeDeploy:
Deployment Automation:
CodeDeploy automates the deployment of a wide array of application content, providing flexibility to deploy code, serverless AWS Lambda functions, web and configuration files, executables, packages, scripts, and multimedia files.
Versatile Deployment Targets:
It facilitates deployments to various targets, including Amazon EC2 instances, on-premises instances, serverless Lambda functions, and Amazon ECS services. This versatility ensures that applications can be seamlessly deployed across different hosting environments.
Content Source Flexibility:
CodeDeploy allows the deployment of application content stored in diverse sources, such as Amazon S3 buckets, GitHub repositories, or Bitbucket repositories. This flexibility ensures that teams can leverage existing version control systems and storage solutions.
Code Compatibility:
An advantageous feature is that CodeDeploy does not necessitate modifications to existing code. Developers can seamlessly integrate CodeDeploy into their deployment pipelines without the need for extensive code changes.
CodeDeploy stands out as a versatile and adaptive deployment solution, offering automation for a broad range of application content across varied hosting environments. It streamlines the deployment process, promoting efficiency and consistency in application delivery.
What is AWS CodePipeline?
AWS CodePipeline stands as a comprehensive continuous delivery service that empowers users to model, visualize, and automate the intricate steps involved in releasing software. With CodePipeline, you can efficiently model and configure distinct stages within the software release process, and it excels at automating the essential steps needed for a continuous and streamlined software release cycle.
Key Aspects of AWS CodePipeline:
Automated Build, Test, and Release:
CodePipeline serves as a catalyst for the automation of critical processes, including build, test, and release. It orchestrates these stages seamlessly, ensuring a smooth and automated transition from code changes to production deployment.
Pipeline History and Visualization:
Offering transparency in the software release lifecycle, CodePipeline provides detailed history reports and visualizations of pipeline status. This feature enables teams to track and understand the progression of each release, fostering visibility and accountability.
Consistent Release Process:
CodePipeline facilitates the establishment of a consistent and standardized release process. By defining and automating release stages, teams can ensure that each software release adheres to predefined standards, reducing the risk of errors and inconsistencies.
Enhanced Delivery Speed and Quality:
One of the primary advantages of CodePipeline is its capability to expedite software delivery while simultaneously enhancing the quality of releases. By automating key processes, CodePipeline minimizes manual interventions, thereby reducing the time required for software delivery.
Integration with External Tools:
CodePipeline supports seamless integration with external tools for source control, build, and deployment. This flexibility enables teams to leverage their preferred tools within the continuous delivery pipeline, adapting CodePipeline to existing workflows.
In essence, AWS CodePipeline emerges as a robust solution for orchestrating and automating the software release lifecycle. Its features contribute to the acceleration of delivery timelines, improved release quality, and the establishment of a standardized and transparent release process.
Step 3: Establishing a CodeDeploy Application and Deployment Group
1. Navigate to the AWS CodeDeploy console and initiate the process by selecting “Create application.”
2. Provide a distinctive name for your application, and in the “Compute platform” section, opt for “EC2/On-premises.” Subsequently, click “Create application.”
3. Once your application is successfully created, proceed to set up a deployment group by selecting “Create deployment group.”
4. Assign a meaningful name to your deployment group, specify the service role, and designate the Amazon EC2 instances where the application will be deployed.
5. Under “Environment configuration,” choose “Amazon EC2 instances” and further define a key-value pair with “Name” as the key and “InstanceName” as the value. It’s crucial to select the instance created in the prerequisites, which already hosts the CodeDeploy Agent.
6. For “Install AWS CodeDeploy Agent” and “Enable load balancing,” opt for “Never” and unselect, respectively.
7. Complete the process by clicking “Create deployment group” to finalize the deployment group configuration.
Congratulations! Your application is now operational on an EC2 IP address. However, the journey doesn’t end here; this deployment has been seamlessly automated through the integration with AWS CodePipeline.
Step 4: Configuring an AWS CodePipeline
1. Proceed to the AWS CodePipeline console and initiate the pipeline creation process by selecting “Create pipeline.”
2. Assign a suitable name to your pipeline and advance to the next stage.
3. Under the “Source” section, opt for “AWS CodeCommit” as the source provider and choose the repository and branch established in Step 1.
4. Specify “AWS CodePipeline” as the “Change detection options” and proceed to the next step.
5. Within the “Build” section, designate “AWS CodeBuild” as the build provider and select the CodeBuild project generated in Step 2. Subsequently, click “Next.”
6. In the “Deploy” section, select “AWS CodeDeploy” as the deployment provider and pick the application and deployment group configured in Step 3. Click “Next” to continue.
7. Perform a final review of the settings and selections before clicking “Create pipeline.” The completion of all steps may take some time.
Congratulations! You have successfully deployed your application on an EC2 IP address, and this entire deployment process has been automated through the robust orchestration of AWS CodePipeline. Leveraging the capabilities of AWS CodeCommit, CodeBuild, and CodeDeploy, you’ve streamlined the workflow, ensuring a seamless and efficient deployment of your application.
Roll back a deployment with CodeDeploy
Initiating a rollback with AWS CodeDeploy involves the redeployment of a prior version of your application, treating it as a new deployment with a distinct deployment ID. This process ensures the restoration of a stable and known state in the event of issues encountered during a recent deployment.
Key points for understanding rollback with CodeDeploy:
Revision Re-Deployment: The rollback essentially entails re-deploying a version of your application that was previously deployed and known to be functioning correctly. CodeDeploy handles this as a separate deployment, maintaining clarity in version control.
New Deployment ID: Despite rolling back to a previous version, each rollback is treated as a new deployment, resulting in a unique deployment ID. This distinction aids in tracking and managing the deployment history effectively.
Redundancy and Reliability: Rollbacks serve as a crucial mechanism for enhancing system reliability. If unexpected issues arise post-deployment, the ability to swiftly revert to a known-working version minimizes downtime and maintains system stability.
Deployment History: AWS CodeDeploy maintains a comprehensive deployment history, capturing details of each deployment and rollback. This historical record offers insights into the evolution of your application and facilitates troubleshooting.
Configuration Flexibility: CodeDeploy allows you to configure rollback strategies based on your specific requirements. Whether it’s an automatic rollback triggered by predefined conditions or a manual initiation, the flexibility in configuration empowers you to tailor the rollback process.
Continuous Improvement: Incorporating rollback procedures into your deployment strategy is a best practice in continuous improvement. It enables development teams to learn from issues, iterate on deployments, and enhance overall application resilience.
By leveraging AWS CodeDeploy’s rollback capabilities, you establish a robust and adaptable deployment pipeline that prioritizes system stability and facilitates a responsive approach to any unforeseen challenges during the deployment lifecycle.
Rollback and redeployment workflow
In the event of an automatic rollback initiation or a manual redeployment or rollback, AWS CodeDeploy follows a meticulous workflow to ensure the integrity of the deployment process. The process involves a series of steps focused on removing files from each participating instance, guided by the contents of a designated cleanup file.
Key aspects of the rollback and redeployment workflow:
- Initiation Triggers: The rollback and redeployment process is set in motion either automatically, triggered by predefined conditions such as deployment failures, or manually initiated by a user. These actions aim to address issues that may have arisen during a recent deployment.
- Cleanup File Verification: CodeDeploy checks for the existence of a cleanup file specific to the deployment group on each instance. The location of this file varies based on the operating system:
For Amazon Linux, Ubuntu Server, and RHEL instances:
/opt/codedeploy-agent/deployment-root/deployment-instructions/deployment-group-ID-cleanup
For Windows Server instances:
C:\ProgramData\Amazon\CodeDeploy\deployment-instructions\deployment-group-ID-cleanup
- File Removal Process: If the cleanup file is present, CodeDeploy utilizes the information within it to systematically remove all listed files from the instance. This ensures a clean slate before commencing the new deployment, mitigating any potential conflicts or discrepancies.
- Deployment Integrity: The objective of this file removal process is to maintain the integrity of the deployment by eliminating remnants of the previous deployment. It establishes a consistent environment for the upcoming deployment, minimizing the likelihood of issues related to existing files.
- Operating System Variations: CodeDeploy accommodates the differences in file system structures between various operating systems. The distinct paths for cleanup file locations on Linux-based and Windows-based instances reflect this adaptability.
Understanding the intricacies of the rollback and redeployment workflow underscores the precision and reliability of AWS CodeDeploy in managing deployment lifecycles. This systematic approach contributes to a streamlined and resilient deployment process for applications hosted on diverse instances.
Detailed Explanation of Rollback Behavior with Existing Content in AWS CodeDeploy:
During the deployment process in AWS CodeDeploy, the CodeDeploy agent takes specific actions concerning existing content on each instance. This behavior is crucial for maintaining the consistency and reliability of deployments. Understanding how CodeDeploy handles existing content, especially in the context of rollbacks, is essential for effective deployment management.
Rollback Behavior:
1. Removal of Files: As a standard part of the deployment, the CodeDeploy agent removes all files that were installed by the most recent deployment from each instance. This step ensures a clean slate for the upcoming deployment.
2. Dealing with Unrelated Files: In cases where files not included in a previous deployment are found in the target deployment locations, you have several options to determine how CodeDeploy should handle them during the next deployment:
- ● Fail the Deployment: If unrelated files are detected, CodeDeploy can report an error, changing the deployment status to Failed.
- ● Overwrite the Content: The version of the file from the application revision replaces the existing version on the instance.
- ● Retain the Content: The file in the target location is preserved, and the version from the application revision is not copied to the instance.
3. User Configuration: The behavior concerning unrelated files can be configured by the user during deployment creation. This flexibility allows users to define how CodeDeploy should interact with existing content based on their specific deployment requirements.
4. Use Cases for Retaining Content: Users might choose to retain files that are not part of the application revision package but are essential for the next deployment. For example:
- ● Uploading files directly to the instance required for the deployment but not included in the application revision bundle.
- ● Uploading additional files to the instance when applications are already in the production environment, and CodeDeploy is introduced for the first time.
Rollbacks and Content Handling:
- ● In the case of rollbacks, where the most recent successfully deployed application revision is redeployed due to a deployment failure, the content-handling option configured during that last successful deployment is applied to the rollback deployment.
- ● An important consideration is that if the deployment that failed was configured to overwrite files instead of retaining them, an unexpected outcome may occur during the rollback. Specifically, files expected to be retained might be removed by the failed deployment, leading to their absence on the instance when the rollback deployment runs.
Understanding these nuanced aspects of rollback behavior ensures that users can make informed decisions during deployment creation and anticipate the consequences of different content-handling choices in AWS CodeDeploy.
Now that we’ve delved into the theoretical concepts, let’s practically explore how CodeDeploy Rollback works by intentionally introducing an error during deployment.
Step-by-Step Guide:
1. Access CodeDeploy:
- ● Navigate to CodeDeploy by using the search bar.
- ● Locate and select your application; for example, “GetFix-Rollback-App.”
2. Edit Deployment Group:
- ● Go to the “Deployment Group” tab.
- ● Select the deployment group you created (e.g., “GetFix-Rollback-App-DG”).
- ● Click on “Edit” to access deployment group settings.
- ● Expand the “Advanced” options.
3. Configure Rollback Settings:
- ● In the “Rollbacks” section, uncheck the “Disable rollbacks” checkbox.
- ● Check the following two checkboxes:
- ● “Roll back when a deployment fails.”
- ● “Roll back when alarm thresholds are met.”
4. Initiate Deployment:
- ● Navigate to the “Deployments” tab below.
- ● Click on the “Create deployment” button.
5. Deployment Configuration:
- ● Select the deployment group you created earlier (e.g., “GetFix-Rollback-App-DG”).
- ● Choose “Revision type” as “My application is stored in Amazon S3.”
6. Specify Revision Details:
- ● In the “Revision location” field, copy and paste the Amazon S3 bucket where your revision is stored. (Note: Deliberately provide incorrect information to simulate a deployment failure.)
- ● Select “.tar.gz” as the “Revision file type.” Instead of .zip( again to simulate a deployment failure.)
7. Create Deployment:
- ● Keep all other settings as default.
- ● Click on the “Create deployment” button.
8. Intentional Error:
- ● Since incorrect information was provided during deployment, it is expected to fail.
9. Rollback Occurs:
- ● Observe that another deployment is triggered automatically.
- ● This new deployment succeeds, indicating that CodeDeploy applied the rollback strategy by reverting to the previously successful deployment.
By intentionally introducing an error during deployment, we validate that CodeDeploy can efficiently handle rollbacks. The platform detects deployment failures and initiates a rollback process, ensuring that the application is rolled back to a known, stable state. This practical demonstration emphasizes the resilience and reliability of AWS CodeDeploy in managing deployments and ensuring continuous delivery.
In conclusion, AWS CodeDeploy’s robust rollback mechanism emerges as a pivotal asset in ensuring the resilience and reliability of deployment processes. By intentionally triggering errors during deployment, we’ve witnessed CodeDeploy’s ability to seamlessly initiate rollbacks, reverting applications to previously successful states. This inherent capability not only safeguards against deployment failures but also underscores CodeDeploy’s commitment to maintaining continuous delivery with precision and efficiency. Embracing CodeDeploy’s comprehensive rollback features empowers developers and devOps engineers to navigate deployment complexities confidently, fostering a streamlined and dependable software release lifecycle.