#
Bonus Hands-On Exercise: Building a Complete Terraform Project with CI/CD
#
Exercise Objective
In this exercise, participants will build a complete infrastructure project using Terraform and integrate it with a CI/CD pipeline to enable automatic deployments. By the end, participants will have a fully automated workflow to manage and deploy infrastructure changes.
#
Steps
#
Step 1: Set Up a Terraform Project Directory Structure
Create the Project Directory:
- In your terminal, create a new directory for the project and navigate into it:
mkdir terraform-cicd-project cd terraform-cicd-project
- In your terminal, create a new directory for the project and navigate into it:
Create the Basic Directory Structure:
- Inside
terraform-cicd-project
, set up the following structure:. ├── main.tf ├── variables.tf ├── outputs.tf ├── dev.tfvars └── prod.tfvars
- Inside
#
Step 2: Define the Infrastructure in Terraform
Create the
main.tf
File:- Open or create
main.tf
in your project directory. Add the configuration for an Azure Resource Group and Virtual Machine:provider "azurerm" { features {} } resource "azurerm_resource_group" "example" { name = var.resource_group_name location = var.location } resource "azurerm_virtual_machine" "example" { name = "example-vm" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name network_interface_ids = [azurerm_network_interface.example.id] vm_size = var.vm_size storage_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } os_profile { computer_name = "examplevm" admin_username = "adminuser" admin_password = "P@ssw0rd123!" } }
- Open or create
Define Variables in
variables.tf
:- Create
variables.tf
with the necessary input variables:variable "resource_group_name" { description = "The name of the resource group" type = string } variable "location" { description = "The Azure location for the resources" type = string } variable "vm_size" { description = "The size of the virtual machine" type = string default = "Standard_DS1_v2" }
- Create
Define Outputs in
outputs.tf
:- Create
outputs.tf
to output important information about the deployed infrastructure:output "resource_group_name" { value = azurerm_resource_group.example.name } output "vm_id" { value = azurerm_virtual_machine.example.id }
- Create
Create Environment-Specific Variable Files:
Define environment-specific values in
dev.tfvars
andprod.tfvars
.dev.tfvars
:resource_group_name = "dev-resource-group" location = "East US" vm_size = "Standard_DS1_v2"
prod.tfvars
:resource_group_name = "prod-resource-group" location = "West US" vm_size = "Standard_DS2_v2"
#
Step 3: Initialize the Terraform Project
Initialize the Project:
- Run
terraform init
to initialize the project and download necessary provider plugins:terraform init
- Run
Run
terraform plan
:- Test the configuration to ensure there are no errors by running:
terraform plan -var-file="dev.tfvars"
- Test the configuration to ensure there are no errors by running:
#
Step 4: Set Up a CI/CD Pipeline (e.g., GitHub Actions)
Create a GitHub Repository:
- Go to GitHub and create a new repository.
- Clone the repository to your local machine and add all files from
terraform-cicd-project
to the repository.
Create a GitHub Actions Workflow File:
- In your project directory, create a
.github/workflows
directory and add a workflow file for Terraform:. └── .github └── workflows └── terraform.yml
- In your project directory, create a
Define the Workflow in
terraform.yml
:Open
terraform.yml
and configure it to automatically runterraform plan
andterraform apply
on the main branch.Example workflow:
name: Terraform CI/CD Pipeline on: push: branches: - main jobs: terraform: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up Terraform uses: hashicorp/setup-terraform@v1 with: terraform_version: 1.0.0 - name: Terraform Init run: terraform init - name: Terraform Plan run: terraform plan -var-file="dev.tfvars" - name: Terraform Apply run: terraform apply -auto-approve -var-file="dev.tfvars" env: ARM_CLIENT_ID: ${{ ERROR }} ARM_CLIENT_SECRET: ${{ ERROR }} ARM_SUBSCRIPTION_ID: ${{ ERROR }} ARM_TENANT_ID: ${{ ERROR }}
Note: This workflow uses environment variables from GitHub Secrets (e.g.,
ARM_CLIENT_ID
,ARM_CLIENT_SECRET
). You must set these in the GitHub repository settings.
Set Up GitHub Secrets for Azure Authentication:
- In your GitHub repository, navigate to Settings > Secrets and variables > Actions and add the following secrets:
- ARM_CLIENT_ID
- ARM_CLIENT_SECRET
- ARM_SUBSCRIPTION_ID
- ARM_TENANT_ID
- In your GitHub repository, navigate to Settings > Secrets and variables > Actions and add the following secrets:
#
Step 5: Test the CI/CD Pipeline
Push Your Code to GitHub:
- Commit and push all files to the main branch of your GitHub repository:
git add . git commit -m "Set up Terraform CI/CD pipeline" git push origin main
- Commit and push all files to the main branch of your GitHub repository:
Monitor the Workflow:
- Go to your GitHub repository, navigate to the Actions tab, and watch the pipeline run.
- The workflow should automatically run
terraform init
,terraform plan
, andterraform apply
, deploying the infrastructure.
#
Step 6: Verify the Deployment in Azure
Log in to the Azure Portal:
- Go to the Azure Portal.
- Verify that the Resource Group and Virtual Machine were created according to the configuration.
Check Output Values:
- After the workflow completes, review the GitHub Actions logs for the output values (such as
resource_group_name
andvm_id
).
- After the workflow completes, review the GitHub Actions logs for the output values (such as
#
Optional: Extend the Pipeline for Multiple Environments
Modify the Workflow for Environment-Specific Files:
- Update the GitHub Actions workflow to support both
dev.tfvars
andprod.tfvars
by using environment branches or workflows that trigger based on specific branches (e.g.,dev
andprod
branches).
- Update the GitHub Actions workflow to support both
Create Separate Branches:
- Use
dev
andprod
branches in GitHub to separate development and production environments in the pipeline.
- Use