CI-CD for .NET projects using GitHub actions, AWS s3 and CodeDeploy
Tags: cicd, aws, githubactions, dotnet
Published: 2023-03-10 09:54:33

In the world of software development, continuous integration and continuous delivery - continuous deployment (CI/CD) has become a common practice to ensure that the code is delivered in a timely and reliable manner. GitHub Actions is an integral part of the GitHub platform, provides a powerful, flexible, and easy-to-use framework for implementing CI/CD workflows. 

In this blog post, we'll explore how to use GitHub Actions to build, test, publish, and deploy .NET applications to an EC2 instance running Windows using AWS CodeDeploy.

**Setting Up the Environment**
Before we get started with building the workflow, we need to ensure that we have the necessary tools and services set up.

Prerequisites
1. A GitHub account.
2. AWS IAM role for ec2, s3 bucket and CodeDeploy.
3. A .NET application hosted on GitHub.
4. An AWS account with S3 bucket and CodeDeploy service.
5. A Windows EC2 instance running IIS with CodeDeploy agent installed creating the workflow.

**IAM configuration:**
1. Navigate to IAM dashboard in AWS console and click on Users.
2. Click on "Roles" and then on create role button.
3. Choose EC2 as the use case and AWS service as the trusted entity type.
4. On the next page add "AmazonS3FullAccess","AWSCodeDeployRole","AmazonEC2RoleforAWSCodeDeploy" in the permission policies and click on create role button. 

**AWS S3:**
1. Navigate to S3 service in AWS.
2. Click on create bucket button.
3. Enter the bucket name, region and modify the settings of bucket if required and click on create bucket button.
4. Create a folder inside the bucket to hold the published files.

**AWS EC2:**
1. In the EC2 service click on launch instance button.
2. Enter the name of the instance, select windows as Application and OS Images.
3. select the instance type as per the requirements.
4. Select the key pair where most commonly used are SSH keys and click on create new key pair.
Note: save the key securely as it is created only once and if it's lost you cannot recover it.
5. Configure the necessary Network and Storage settings and finally hit launch instance.

**AWS CodeDeploy:**
1. In the CodeDeploy service click on create application.
2. Enter the application name and select compute type as EC2/On-premises.
3. On the next page click on create deployment group button and enter the name.
4. Select the service role which you've created while creating IAM role.
5. Select Amazon EC2 instance and enter the key-pair of the EC2 instance where you want to deploy the application.
6. After the necessary configurations for CodeDeploy service click on create deployment group.
7. Next click on create deployment and select "My application is stored in GitHub".
8. Enter the GitHub profile name as token name and connect to GitHub profile, After creating the deployment this would trigger the deployment to EC2 instance.

**GitHub Actions configuration:**
We'll start by creating a new workflow in our .NET application's GitHub repository. A workflow is a series of steps that define how our code should be built, tested and deployed.

Go to your GitHub repository and select the Actions tab.

Click on the "New workflow" button and choose "Set up a workflow yourself".

Give your workflow a name and add the following YAML code to define the steps:

yaml:
```
name: CI-CD Workflow

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: windows-latest

    steps:
    - name: Checkout Code
      uses: actions/checkout@v2
      
    - name: Setup .NET
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: '6.0.x'

    - name: Build and Test
      run: dotnet build && dotnet test
      
    - name: Publish
      run: dotnet publish -c Release -o ./publish
      
    - name: zip publish
      run: Compress-Archive -Path ./publish -DestinationPath ./publish/publish.zip

    - name: Configure AWS credentials from Test account
      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: {aws-region}

    - name: Upload to S3
      run: | 
        aws s3 cp ./publish s3://{bucket-name}/{folder-name}/ --recursive

    - name: Deploy to EC2 instance
      run: |
        aws deploy create-deployment --application-name {application-name} --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name {deployment-group-name} --s3-location bucket={bucket-name},key={folder-name}/publish.zip,bundleType=zip


```

The workflow consists of the following steps:
Checkout Code: Check out the code from the GitHub repository.
Setup .NET: Set up the .NET runtime on the build machine.
Build: Compile the application in release mode.
Test: Run the unit tests for the application.
Publish: Publish the application to the publish folder.
Zip: Compress the publish folder into a single zip file.
Upload to S3: Upload the zip file to an S3 bucket.
Deploy: Trigger an AWS CodeDeploy deployment using the zip file in the s3 bucket.

**Conclusion**
In this blog post, we've seen how to use GitHub Actions to build, test, publish, and deploy. NET applications to an EC2 instance running Windows using AWS CodeDeploy. By automating the build, test, and deployment process, we can ensure that our application is delivered in a timely and reliable manner. By using the power of AWS services like S3 and CodeDeploy, we can achieve a robust and scalable deployment process for our .NET applications.