2-stage CICD pipeline using Terraform
Published: 2024-01-10 12:27:54

Intoduction
In my previous article, we explored the capabilities of automated code delivery, elevating our development workflow with precision and ease through AWS CI/CD developer tools. In that tutorial, we successfully implemented a two-stage CI/CD pipeline using AWS CodePipeline, CodeCommit, and CodeDeploy, all managed seamlessly through the AWS Management Console.
https://dev.to/gbenga700/implementing-a-two-stage-codepipeline-with-codecommit-and-codedeploy-5fak
Now, let's take it a step further by demonstrating how we can achieve the same application deployment using Terraform, an Infrastructure as Code (IaC) tool. This approach not only provides us with reusable code for deployment but also introduces additional flexibility and control over our infrastructure. For brevity, we will zoom in on the implementation of Terraform modules.
To access the complete Terraform code, you can find the repository in the link below. Dive into the modules, where the core infrastructure logic resides, providing a clear and concise representation of our deployment strategy.
https://github.com/7hundredtech/Terraform_AWS_Codepipleine/tree/main/terraform

**Overview of my project folder**


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3fsgvdbgyj19zzwi3mq1.png)

**Modules folder:** This folder consists of all the terraform codes for all the services required from this project. Please see the repo link provided above for details. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7ixpn3zea7y4nf1e4rd.png)
**Ec2.sh file :** This is a user data file for our instance. It automatically downloads CodeDeploy agent on our instance at launch.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/epx9au7o7dfpyqtreeer.png)
**Main.tf file:** This file consists of the detailed infrastructure to be deployed as extracted in each AWS service folder from the Modules folder.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qucagbfwtwvz9cg7kt3z.png)
**Output.tf file:** This file consists of the outputs that will be displayed on our terminal after running _terraform Apply_ command.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ett7fltdqupb4dtmze3.png)
**terraform.tf file:** This file specifies the terraform provider and version in use. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gcmtevdp92favbz6fsty.png)

**terraform.tfvars file:** This file allows us to pass our variable values with putting them directly in the code.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il5el7opilfhzw3qjj8b.png)
**variable.tf file:** This file shows the list of the variables used in the project.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ukslmi6gppecs5xbgfpi.png)

**Initializing Terraform**
Change directory into the project folder, open integrated terminal  and run **terraform init** command.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/donserk638qik6hmqq2a.png)
Run **terraform validate** to confirm that our configurations are valid.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xzo055m5beiiyvxnqxq.png)
Run **terraform plan** to display the plan of the infrastructures that we be deployed. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hz3has4hzg1ydpxjsmeh.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93fhiejpekiy4ujs1brn.png)
Run **terraform apply** to deploy the infrastructure. Ensure you approve with a **yes**.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uw5pah0kq1xbeq3f68ft.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qekynugfyfnbqy21dty9.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/326clfztqvvp9ger3ot6.png)
**Let’s confirm our infrastructures from the AWS console.**

**Ec2 instance**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vih0yecl02gv6ia8g9qx.png)

**CodeCommit Repository**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wwjx338mjww83id10lr.png)
**CodeDeploy Application and Deployment Group**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d8pgyt2ixi05d43cq2h5.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zym1ti4c7wx8axssh92s.png)
**IAM Roles**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gwjsiydr8i8g1f6fpnl.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/linkfvsyt9ylwe24968a.png)
**CodePipeline**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eqf3xb2js94bddqan63q.png)

Note that the code pipeline failed because our repository is still empty without any code to deploy.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t8aj9hc32xvt2qvmvvk.png)
**To update our CodeCommit Repository with Codes.**
Copy the repository url from the output of the terraform apply command as seen below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbjeywgd1hj0vk8ds437.png)

Clone the repository in your project folder using the git clone command.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vajprd47v8bwazektslt.png)
CD into the repository folder and copy the application files it.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/trmor7z07b6miur02yq4.png)
Stage, commit and push the files to the remote repository.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pt7mydp7bd7pmkn6ric4.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czcwp9r9j4e7t155r2nm.png)
Let’s confirm from the AWS console that the codes have been pushed successfully.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9j8i55buo571sd8tcol5.png)

The CodePipeline is also triggered simultaneously and successful this time.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jbnuklwt9ama6aa0x4k.png)

Run the **terraform output** command to get our server public dns endpoint.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2o4yd77pa59dvetvj2e.png)
Copy and past on your web browser to display the web page.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/foopouk0yayw3r7mrz86.png)

Lets verify the pipeline is working by effecting a change in our code. 
Change the background colour in the index.html file  to #FF0000 “red” and “Congratulations” to **Pipeline deployed using terraform codes!!!**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nx4gu8tswza6zo3u8xcg.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/etywghkd710shacc9vxc.png)
Stage, Commit and Push the changes to the remote CodeCommit repository


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6t329mcxxcbrpbdcbgqr.png)

This automatically triggers the pipeline

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4pxt864n4sn55e6ibkht.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6wa0ji367aladya9tja.png)
Refresh your browser to see the change.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/155n3xq4t7ioit8bpw1p.png)
Congratulations!!! the pipeline is working as designed.

**Clean Up**
Run terraform destroy to remove all infrastructures deployed to avoid unexpected bills

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2w4maja3kkgqv4zanin.png)