Platform Engineering with Pulumi — Episode 3: Platform & Application Deployment with GitOps Automation
Tags: gitops, javascript, python, aws
Published: 2022-01-18 12:21:50


## Platform Engineering with Pulumi — Episode 3: Platform & Application Deployment with GitOps Automation

### Automate the deployment of the app with GitActions and CodeDeploy.

![](https://cdn-images-1.medium.com/max/NaN/1*PqvYUGoCgCAskeybM-o_GA.png)

In [Episode 1](https://aws.plainenglish.io/platform-engineering-with-pulumi-episode-1-building-the-aws-landing-zone-with-pulumi-67b559523c78) of this blog series, we built an AWS landing zone for our React/Node.js application, using Pulumi. In [Episode 2](https://aws.plainenglish.io/platform-engineering-with-pulumi-episode-2-building-and-deploying-the-nodejs-application-6217ed039e6) we built a simple React app and an Express API server. We manually deployed the app on the landing zone. In this episode, we will automate it with GitActions and CodeDeploy.
>  For the sample application used in this blog, I have used Multi-repo. There is a huge debate on Mono vs Multi Repos. I might blog about that separately, but for now let's assume Multi repo is the best for this application and go ahead :-D.

Before we configure the GitActions, we have to modify the infrastructure code to include Infra code for the creation of code deploy configurations.

## Modifying the Infra code to create CodeDeploy

In [Episode 1](https://aws.plainenglish.io/platform-engineering-with-pulumi-episode-1-building-the-aws-landing-zone-with-pulumi-67b559523c78), we did not create the CodeDeploy Configurations. Find below the modifications done in the Python code to create appropriate Roles and CodeDeploy configurations. Let's walk through the code (*please refer to my [**GitHub](https://github.com/abvijaykumar/contactlist-blog-infra)** for more latest code.*)

![](https://cdn-images-1.medium.com/max/2000/1*J1oNCEB9AtfcGZrDdJvqsQ.png)

In the above code, We are creating a Role, to allow the CodeDeploy service to have access, and attaching appropriate access policies (AmazonEC2FullAccess, AWSCodeDeployFullAccess, AdministratorAccess, AWSCodeDeployRole).

Let's now create the CodeDeploy application

![](https://cdn-images-1.medium.com/max/2692/1*D-pg-ALLcmlmQihXkexSuw.png)

In the above code, we are creating a CodeDeploy application. Let's now create deployment groups.

![](https://cdn-images-1.medium.com/max/2000/1*aKFxSHfJtdOHDdJ5kBlKDg.png)

In the above code, we are creating a CodeDeploy Deployment Group, with the Role that we created. This deployment group will be used to deploy API code (Node.js/Express). The below code created a CodeDeploy Deployment Group to deploy the React application. Both the deployment groups are created under the same CodeDeploy Application

![](https://cdn-images-1.medium.com/max/2000/1*-EUXjs2Vfzfqk_8sC7CyrQ.png)

Let's now run the code withpulumi up.

## GitOps Deploying Node.js API application

Now that we have all the infrastructure ready.

Lets first create a CodeDeploy Configuration file (appspec.yml) in our Node.js application.

![](https://cdn-images-1.medium.com/max/2000/1*pz2EolFkbxVV4yZwPsvFjQ.png)

In the appspec.yml, we are configuring the source and destination (on EC2) folders. This configuration is used by CodeDeploy to deploy the application files in the appropriate folder (/home/ec2-user/contacts-api).

We are also configuring 2 Hooks

* **Before Install Hook**: This is a shell script that we are asking CodeDeploy to run, before deploying the application code. In this shell script, we will set up the environment required. The following is the code for setup.sh. In this shell script, we are installing NVM and creating a directory for CodeDeploy to deploy the source files:

![](https://cdn-images-1.medium.com/max/2588/1*8Zud5pL5CF9OWrvANMX9yw.png)

* **Application Start Hook**: Which is another shell script that we are asking CodeDeploy to run to start the application after deploying the application code. The following is the code for appStart.sh, where we are setting up the nvm environment variables, running npm install to install all the dependencies, and then running our application.

![](https://cdn-images-1.medium.com/max/2384/1*JgmNIKaH5iAztHqaQJyjvA.png)

Let's now build a GitOps pipeline for the NodeJS application. The following is the code for GitActions, which gets triggered on pull request and push.

![](https://cdn-images-1.medium.com/max/2000/1*pW6DYLH27BjKDdAZ3Z68hQ.png)

The above code is very simple. We are using a ubuntu-latest VM instance, setting the AWS credentials (the AWS_IAM_ACCESS_KEY, AWS_SECRET_ACCESS_KEY and AWS_REGION configurations are already configured in GitHub under Settings->Secrets. Here is a screenshot).

![](https://cdn-images-1.medium.com/max/3476/1*XNlpV2JCrK7HrOMYwV6DwA.png)

We are then triggering the appropriate CodeDeploy deployment group, that we have configured using Pulumi in the above section.

Now that we have all the pipeline code, let's test it by running the GitActions Workflow. The following animated gif shows the execution of the workflow and the deployment.

Let’s now automate the deployment of the React app.

## GitOps Deploying React application

To deploy React, the steps are similar, We first configure the AWS key, region, and secret in GitHub secrets.

![](https://cdn-images-1.medium.com/max/NaN/1*iQegcWYOvAUnw8GXRh3J-Q.png)

Let's create the GitActions workflow. The following is the code:

![](https://cdn-images-1.medium.com/max/2976/1*mEDblZPStXxNGLitv1KuoA.png)

This code is very similar to how we deployed Node.js except that the deployment group we are using for React is different. We are using pulumi-blog-app-codedeploy-deploymentgroup.

Let's add the appspec.yml in the React root folder. The following is the source code. Similar to what we did with the Node.js application, we have 2 hooks, one to set up the environment and the other script to start the application.

![](https://cdn-images-1.medium.com/max/2000/1*nWGpGahHvCuW8C4Bj7hFPg.png)

Let's create the startup.sh, where we set up the environment before we deploy the application.

![](https://cdn-images-1.medium.com/max/2828/1*RY-dAjhXmaHfeQunTS7ddA.png)

In the above code we are installing nvm, and making sure contacts-app the folder is created.

The following is the code for running the application.

![](https://cdn-images-1.medium.com/max/2000/1*dYdVBFPv2CpPrFCu5XsHGA.png)

In the above script, we are installing pm2 & serve, building the application, and running the application. These are the exact steps we followed in [Episode 2](https://aws.plainenglish.io/platform-engineering-with-pulumi-episode-2-building-and-deploying-the-nodejs-application-6217ed039e6).

Let's now execute the workflow. The following is the screen capture video of the workflow execution.

Now we have all the pipelines configured whenever there are changes to the application code, the respective GitAction workflow will deploy the application to the EC2 instance.

We need one more GitOps pipeline for the Infrastructure code. I thought of covering that in this episode..but it has already become a long one. So I will be publishing the same in the next Episode.

Until then take care and Have fun, hope this was helpful :-D

## References

* React app Repository: [https://github.com/abvijaykumar/contactlist-blog-react-app](https://github.com/abvijaykumar/contactlist-blog-react-app)

* Express API repo: [https://github.com/abvijaykumar/contactlist-blog-app](https://github.com/abvijaykumar/contactlist-blog-app)

* Pulumi Infrastructure code repo: [https://github.com/abvijaykumar/contactlist-blog-infra](https://github.com/abvijaykumar/contactlist-blog-infra)
[**community Discord](https://discord.gg/GtDtUAvyhW)**.*