CI/CD pipeline on AWS (Part - 3) CodeDeploy

CI/CD pipeline on AWS (Part - 3) CodeDeploy

Day 52 of 90daysofdevops

ยท

7 min read

What is CodeDeploy?

  • AWS CodeDeploy is a deployment service that automates application deployments to Amazon EC2 instances, on-premises instances, serverless Lambda functions, or Amazon ECS services.

  • CodeDeploy can deploy application content that runs on a server and is stored in Amazon S3 buckets, GitHub repositories, or Bitbucket repositories. CodeDeploy can also deploy a serverless Lambda function. You do not need to make changes to your existing code before you can use CodeDeploy.

Appspec file for CodeDeploy

  • The AppSpec (Application Specification) file is used in AWS CodeDeploy.The AppSpec file is a YAML-formatted configuration file that defines the deployment instructions for your application.

  • The AppSpec file specifies the source files to be deployed, the deployment target, and the actions to be performed during the deployment process. It is typically placed in the root directory of your deployment package or source code repository.

Key elements of an AppSpec file:

Version

Specifies the version of the AppSpec file format. The current version is "0.0".

version: 0.0

Resources

  • Defines the resources involved in the deployment. The primary resource is the instance or instances on which the deployment is performed.

  • You can also specify other resources like load balancers, Amazon RDS database instances, or Amazon ECS task sets.

resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: my-task-definition
        LoadBalancerInfo:
          ContainerName: my-container
          ContainerPort: 80

Hooks

  • Defines the lifecycle event hooks, which are scripts or commands executed at different stages of the deployment process.

  • Hooks allow you to perform actions before or after specific deployment events.

  • Common hooks include "BeforeInstall," "AfterInstall," "ApplicationStart," and "ValidateService."

      hooks:
        BeforeInstall:
          - location: scripts/install_dependencies.sh
            timeout: 300
            runas: root
    
    • In this case, the "BeforeInstall" hook runs the specified script (install_dependencies.sh) before the application installation process. The timeout and the user context (root) for running the script are also specified.

Files

  • Specifies the source files to be deployed and their destination paths on the target instances. This section allows you to map files from your deployment package to specific locations in the target environment.

      files:
        - source: /dist/myapp
          destination: /var/www/html
          owner: webuser
          group: webgroup
          permission: '755'
    
    • In this example, the /dist/myapp directory from the source package will be deployed to /var/www/html on the target instances. The owner, group, and permissions of the deployed files can also be specified.

Permissions

  • Specifies the permissions for the deployment actions, allowing you to control access to specific resources during the deployment process.

      permissions:
        - object: /var/www/html/private
          pattern: "**"
          owner: webuser
          group: webgroup
          mode: '400'
    

Task-01 :

  • Read about Appspec.yaml file for CodeDeploy.

  • Deploy index.html file on EC2 machine using nginx

  • you have to set up a CodeDeploy agent in order to deploy code on EC2


Deploy index.html file on EC2 machine using nginx

  • For code commit and code build steps, please follow Day 51 task article.

Create a CodeDeploy application

  • In AWS Management Console search CodeDeploy. Once you are into the CodeDeploy go to Applications which is inside Deploy and click on 'Create application'.

  • Select compute platform 'EC2/on premises' and click on 'Create application'.

  • The application is successfully created.

  • Create a new service role for enabling communication between code deploy and other AWS services.

    Go to IAM service and create 'code-deploy-service-role' with permissions.

    "AmazoneEC2FullAccess", "AmazoneS3FullAccess", "AWSCodeDeployRole", "AmazoneEC2RoleforAWSCodeDeploy", "AWSCodeDeployFullAccess", "AmazonEC2RoleforAWSCodeDeployLimited".

  • Change the Trust Relationship

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Service": [
                          "codedeploy.amazonaws.com"
                      ]
                  },
                  "Action": "sts:AssumeRole"
              }
          ]
      }
    

Set up an EC2 instance

  • You will need to create an EC2 instance on which you want to deploy the index.html file.

    Create a Ubuntu EC2 instance

Create a deployment group

  • Once you have created a CodeDeploy application, you need to create a deployment group. A deployment group is a set of EC2 instances where you want to deploy your application.

  • Add a deployment group name and choose the Service role where we provide all the permission policies.

  • Provide the EC2 instance name that was created before.

  • Click on 'Create deployment group'.

  • A deployment group is created.

Setup a CodeDeploy agent to deploy code on EC2

  • Install the CodeDeploy agent:

    You need to install the CodeDeploy agent on your Ubuntu EC2 instance. The CodeDeploy agent is a software package that runs on your instance and interacts with CodeDeploy to deploy your application.

  • You can install the CodeDeploy agent by running the following script on your EC2 instance:

        #!/bin/bash 
        # This installs the CodeDeploy agent and its prerequisites on Ubuntu 22.04.  
        sudo apt-get update 
        sudo apt-get install ruby-full ruby-webrick wget -y 
        cd /tmp 
        wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/releases/codedeploy-agent_1.3.2-1902_all.deb 
        mkdir codedeploy-agent_1.3.2-1902_ubuntu22 
        dpkg-deb -R codedeploy-agent_1.3.2-1902_all.deb codedeploy-agent_1.3.2-1902_ubuntu22 
        sed 's/Depends:.*/Depends:ruby3.0/' -i ./codedeploy-agent_1.3.2-1902_ubuntu22/DEBIAN/control 
        dpkg-deb -b codedeploy-agent_1.3.2-1902_ubuntu22/ 
        sudo dpkg -i codedeploy-agent_1.3.2-1902_ubuntu22.deb 
        systemctl list-units --type=service | grep codedeploy 
        sudo service codedeploy-agent status
    

  • Run the script using bash command.

  • We can verify the status that Code Agent is running.

  • Create an index.html file:


Task-02 :

  • Add appspec.yaml file to CodeCommit Repository and complete the deployment process.

Create an appspec.yaml file:

  • You need to create an appspec.yaml file that tells CodeDeploy what to do with your application.

  • Here is an appspec.yaml file that deploys the index.html file on nginx. also, create 2 scripts for installing nginx and starting nginx.

    version: 0.0
    os: linux
    files:
      - source: /
        destination: /var/www/html
    hooks:
      AfterInstall:
        - location: scripts/install_nginx.sh
          timeout: 300
          runas: root
      ApplicationStart:
        - location: scripts/start_nginx.sh
          timeout: 300
          runas: root
  • Create start_nginx.sh in the scripts folder
#!/bin/bash

sudo service nginx start
  • Create install_nginx.sh in the scripts folder
#!/bin/bash

sudo apt-get update
sudo apt-get install nginx -y

  • Push all the files to code commit using 'git add' and 'git commit' commands.

  • All the files are updated in the CodeCommit.

  • Add changes to the buildspec.yml file

      version: 0.2
    
      phases:
        install:
          commands:
            - echo Installing NGINX
            - sudo apt-get update
            - sudo apt-get install nginx -y
        build:
          commands:
            - echo Build started on 'date'
            - cp index.html /var/www/html/
        post_build:
          commands:
            - echo Configuring NGINX
    
      artifacts:
          files:
            - '**/*'
    

  • In build projects, Edit and choose 'Artifacts'.

  • Create a new S3 bucket.

  • In Artifacts, select artifact type as Amazon S3 and choose bucket name.

  • Click on 'Update artifacts'.

  • Artifact upload location successfully added. Click on 'Start build'.

  • The build is Succeeded.

  • After building completion, go to the S3 bucket and copy the S3 URL of the nginx_app-dep zip file.

Create deployment:

  • In the Application, Go to Deployments and click on 'Create deployment'

  • In revision type, select Amazon S3 and paste the above copied S3 url to the revision location

  • Click on 'Create deployment'.

  • Deployment is created. but events are in a pending state.

  • EC2 doesn't have any role policy to retrieve the data from S3 to CodeDeploy.

    To create a new service role for enabling communication between EC2 and S3, code deploy.

    • Go to IAM service and create 'EC2-S3-CodeDeploy' with permissions.

      "AmazoneEC2FullAccess", "AmazoneS3FullAccess", "AWSCodeDeployFullAccess".

  • Attach that service role to the EC2 instance.

    Select EC2 instance, In actions, go to security and click on 'Modify IAM role'.

    Select the service role that we created in the above steps.

  • After updating the IAM role, restart the code-deploy agent.

      sudo service codedeploy-agent restart
      sudo service codedeploy-agent status
    

  • Deployment status is Succeeded.

  • All events Succeeded.

  • Browse the instance public IP address, it will show the output of the index.html file.


Thank You,

I want to express my deepest gratitude to each and every one of you who has taken the time to read, engage, and support my journey.

Feel free to reach out to me if any corrections or add-ons are required on blogs. Your feedback is always welcome & appreciated.

~ Abhisek Moharana ๐Ÿ™‚

ย