14. CI/CD (Back end)
Tags: aws, github
Published: 2021-01-08 01:09:29

After setting up the git repository for my backend infrastructure  ([read more](https://dev.to/jicoing/12-infrastructure-as-code-1df4)), it was time to automate the stack deployment as a CI/CD 
 pipeline for my [website](https://www.komlalebu.com). I don't claim any expertise in this matter, however this [article](https://mechanicalrock.github.io/2020/01/06/github-actions-for-sam.html) guided me.

Git: https://github.com/jicoing/git-komlalebu-sam

#[Git Actions](https://github.com/features/actions)
GitHub Actions makes it easy to automate all your software workflows and deploy your code right from GitHub.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2iy8j5hj0l2r7to4dqf0.PNG)


 
Github [actions](https://docs.github.com/en/free-pro-team@latest/actions) integrates with [SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) and deploys my application stack in AWS from my repository code. Rough process diagram shown below: 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/h27imgbq75s8cf03u19q.PNG)

# [Action](https://github.com/falnyr/aws-sam-deploy-action)
After a lot of search I finally found a git action ([Refer](https://github.com/falnyr/aws-sam-deploy-action)) that worked for me! It integrated with my `template.yml` and deployed the stack after a few configurations to the files. So I went ahead and created my own action after learning.

* I setup my `.git/actions/sam/package` folder as below.
This particular folder includes three files  action.yaml, a dockerfile and a entry-point script for the dockerfile.

Tree:

git-komlalebu-sam
 ┣ 📂.github
 ┃ ┣ 📂actions
 ┃ ┃ ┗ 📂sam
 ┃ ┃ ┃ ┗ 📂package
 ┃ ┃ ┃ ┃ ┣ 📜action.yml
 ┃ ┃ ┃ ┃ ┣ 📜Dockerfile
 ┃ ┃ ┃ ┃ ┗ 📜entrypoint.sh
 ┃ ┗ 📂workflows
 ┃ ┃ ┗ 📜ci.yml
 ┣ 📂komla_function
 ┃ ┣ 📜app.py
 ┃ ┗ 📜__init__.py
 ┣ 📂tests
 ┃ ┣ 📜test_handler.py
 ┃ ┗ 📜__init__.py
 ┣ 📜README.md
 ┣ 📜requirements.txt
 ┗ 📜template.yaml



> # ci.yml
Let’s take a look at `ci.yml`. 
* The action has two jobs `test` and `deploy`.
 `test` - checks the integrity of my lambda function.
 `deploy` - deploys the entire SAM stack in AWS and needs `test` to be successful as a dependency. The workflow is triggered on every push to the repository.

                jobs:
                  test:
                  delpoy:
                        needs:test


>
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kx2cx99bacjvi7m33cjm.PNG)

> Test job :
The test job uses `ubuntu-latest` image. Installs python 3. Uses two standard actions in here - actions/checkout@v1 and actions/setup-python@v1. Installs dependencies such as `pip` and installs the dependencies from  `requirements.txt` file we generated during our local testing ([read more]()). Then it runs the test using `pytest`.

> Deploy job :
Once the `test` job is successful, only then `deploy` job starts.
The `jobs` determine the actions that take place during the workflow, and in what order. The job uses `ubuntu-latest` image. The uses statement defines a particular action that we want to use. There is a standard action in here - actions/checkout@v1 and uses `./.github/actions/sam/package` as the path to my action files.

* The workflow uses files present in

                             ./.github/actions/sam/package
     📂actions
     ┗ 📂sam
       ┗ 📂package
         ┣ 📜action.yml
         ┣ 📜Dockerfile
         ┗ 📜entrypoint.sh

> # action.yml

The action.yaml file details metadata about the particular action. It uses the image defined in `Dockerfile`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nzj2odwazy0ujwxxhfbp.PNG)

> # Dockerfile

I configure my dockerfile to build a docker image `alpine:latest` and run the `GLIBC_VER=2.31-r0'` environment on it and setup `awscliv2` on it. I had to adds glibc and then removes some stuff.
([Refer](https://stackoverflow.com/questions/61463584/docker-image-with-aws-cli-v2-and-dind-based-on-alpine3-11)).
Copy the code file from my action repository to the filesystem path `/` of the container `COPY entrypoint.sh /entrypoint.sh`([Refer](https://docs.github.com/en/actions/creating-actions/dockerfile-support-for-github-actions#about-dockerfile-instructions)). However, I was facing continuous `Permission denied` exception so had to add the below command:
`RUN ["chmod", "+x", "/entrypoint.sh"]`. ([Refer](https://stackoverflow.com/questions/54336677/error-starting-container-process-caused-exec-docker-entrypoint-sh-permi)).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/va71pnkb7ix12vm4i4xs.PNG)

> # entrypoint.sh

Most of the work is done by this file in the docker image.
It is the same code as used in this action ([Refer - falnyr/aws-sam-deploy-action](https://github.com/falnyr/aws-sam-deploy-action)). The script basically configure an AWS profile with my credentials, and `packages` and `deploys` the SAM template I developed previously in `template.yml` file ([read more](https://dev.to/jicoing/12-infrastructure-as-code-1df4)).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f63cra3k1sbb6lbm0fq8.PNG)



> # Secrets
The below parameters have 
been passed as environment variables for security purposes.

AWS_ACCESS_KEY_ID
AWS_DEPLOY_BUCKET
AWS_SECRET_ACCESS_KEY

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t0s0fh217ok7ly71f20o.PNG)

# git `push`.

>CMD

                 C:\Users\USER_NAME\git-komlalebu-sam>git add .
                 C:\Users\USER_NAME\git-komlalebu-sam>git commit -m master
                 C:\Users\USER_NAME\git-komlalebu-sam>git push origin master

> # Workflow - Github Actions.

Completion status of the two jobs. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3vazsu5c64o7i9a3wvqr.PNG)

> # AWS Cloudformation stack creation events. 

The stack primarily consists of an API, a lambda function and a DynamoDB table. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8qnuo71ww4syg61u501q.PNG)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0vobgcej8t0ytnl5d9l4.gif)