CI / CD for a project on GitHub deploying to AWS EC2

We have: a web API project on .net core with sources in GitHub.





What we want: auto-deployment on the AWS EC2 virtual machine after finishing working with the code (for example, push to the develop branch).





Toolkit: GitHub Actions, AWS CodeDeploy, S3, EC2.





Below is the flow of the process that we will implement.





Basic CI / CD flow
Basic CI / CD flow

1. Users and roles

1.1. User to access AWS from GitHub Action

This user will be used to connect to AWS S3 and CodeDeploy services via AWS CLI 2 when running GitHub Actions.





1. AWS IAM, User, Add User





2. Programmatic access





Create a new user

3. , Permissions Attach existing policies directly AmazonS3FullAccess AWSCodeDeployDeployerAccess.





4. , Review :





Final result

5. Create user . Access Key ID Secret Access Key .





1.2. AWS EC2

EC2, , AWS CodeDeploy.





  1. AWS IAM, Role, Add Role





  2. AWS Service, Choose a use case EC2





  3. AmazonEC2RoleforAWSCodeDeploy.





  4. Review





  5. , , ProjectXCodeDeployInstanceRole Review :





1.3. AWS CodeDeploy

AWS CodeDeploy AWS EC2.





1. AWS IAM, Role, Add Role





2. AWS Service, Use case CodeDeploy:





Role creation

3. , (AWSCodeDeployRole)





4. , , ProjectXCodeDeploy Review :





The final result of creating a role

2. AWS EC2

  1. AWS EC2





  2. ProjectXCodeDeployInstanceRole, 1.2





  3. CodeDeploy Agent . .





: , , sudo service codedeploy-agent restart







3. AWS CodeDeploy

1. AWS CodeDeploy





2. Deploy, Applications





3. Create application





4. , , projectx Compute platform EC2/On-Premises





New app

5. , Create deployment group





6. , develop . , 1.3 (ProjectXCodeDeploy).





7. Deployment type In place ( ).





8. Environment configuration Amazon EC2 Instances .





4. AWS S3

AWS S3.





  1. AWS S3, Create bucket.





  2. , , projectx-codedeploy-deployments. Block all public access. Create bucket.





Creating a new S3 bucket
S3

5. appspec.yml

, CodeDeploy Agent . AWS CodeDeploy appspec.yml. :





version: 0.0
os: linux
files:
  - source: /
    destination: /opt/projectx
permissions:
  - object: /opt/projectx
    owner: ubuntu
    group: ubuntu
    type:
      - directory
      - file
hooks:
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
      runas: ubuntu
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: ubuntu
      
      















  1.  





  2. appspec.yml version: 0.0 os: linux files:





, ( 4), ( 5) ( 6-12). . .





: 0.0, .. CodeDeploy - 0.0 Β―\_(ツ)/Β―. : ApplicationStop, . , , . ApplicationStop .





6. GitHub Actions

, CI/CD pipeline GitHub Actions.





6.1.

GitHub Settings, Secrets :





  • AWS_ACCESS_KEY_ID: 5 1.1 AWS





  • AWS_SECRET_ACCESS_KEY: 5 1.1 AWS





6.2.

.github/workflows



. pipeline'. , , develop.yaml. :





name: build-app-action
on: 
  push:
    branches:
      - develop
jobs:
  build:
    name: CI part
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.101
      - name: Install dependencies
        run: dotnet restore
      - name: Build
        run: dotnet build --configuration Release --no-restore
  
  deploy:
    name: CD part
    runs-on: ubuntu-latest
    strategy:
      matrix:
        app-name: ['projectx']
        s3-bucket: ['projectx-codedeploy-deployments']
        s3-filename: ['develop-aws-codedeploy-${{ github.sha }}']
        deploy-group: ['develop']
    needs: build
    steps:
      - uses: actions/checkout@v2
      # set up .net core
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.101
      # restore packages and build
      - name: Install dependencies
        run: dotnet restore
      - name: Build
        run: dotnet build ProjectX --configuration Release --no-restore -o ./bin/app
      # copying appspec file
      - name: Copying appspec.yml
        run: cp appspec.yml ./bin/app
      # copying scripts
      - name: Copying scripts
        run: cp -R ./scripts ./bin/app/scripts
      
      # Install AWS CLI 2
      - name: Install AWS CLI 2
        run: |
          curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
          unzip awscliv2.zip
          sudo ./aws/install
      # Configure AWS credentials
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-south-1
      # Deploy push to S3
      - name: AWS Deploy push
        run: |
          aws deploy push \
          --application-name ${{ matrix.app-name }} \
          --description "Revision of the ${{ matrix.appname }}-${{ github.sha }}" \
          --ignore-hidden-files \
          --s3-location s3://${{ matrix.s3-bucket }}/${{ matrix.s3-filename }}.zip \
          --source ./bin/app
      # Creating deployment via CodeDeploy
      - name: Creating AWS Deployment
        run: |
          aws deploy create-deployment \
          --application-name ${{ matrix.app-name }} \
          --deployment-config-name CodeDeployDefault.AllAtOnce \
          --deployment-group-name ${{ matrix.deploy-group }} \
          --file-exists-behavior OVERWRITE \
          --s3-location bucket=${{ matrix.s3-bucket }},key=${{ matrix.s3-filename }}.zip,bundleType=zip \
      
      



: , ( needs deploy, 31). push develop ( 2-5).





build





 .net, . 11-19. Ubuntu ( 9 23) unit-. , deploy.





deploy





.





  • app-name: 4 3 CodeDeploy





  • s3-bucket: , 2 4





  • s3-filename: ,





  • deploy-group: 6 3.





build:  .net, , ( , .., , , ) (./bin/app , 48). appspec.yml ( 43-48). 51 AWS CLI v2, action GitHub. AWS CLI2, GitHub , 6.1, AWS. AWS S3 . AWS CodeDeploy. GitHub Actions.





After that, AWS CodeDeploy will notify the EC2 instances that have been configured in it about the presence of a new build, the CodeDeploy Agent will descend to AWS S3 for a new version and deploy it. You can watch this from the AWS CodeDeploy console.





Let's summarize

At this point, we have completely completed the configuration and you can try to push to GitHub and check how it all worked .. or not :) Along the way, I tried to highlight the rake that I stepped on during the trial setup, so I hope you did it immediately.





The resulting description of the pipeline can be tuned further, screwed on various checks of the source code for bugs, vulnerabilities, run tests, add different triggers and roll out into different circuits.
















All Articles