Terraform & Ansible Scalable IaC Project

September 1, 2023 (1y ago)

Infrastructure as Code Project with Terraform and Ansible

This is the final project for the Automation course at Humber College CCGC 2023. The project uses Terraform to provision Azure resources and Ansible to configure the Linux VMs.

This is the result of many hours of hard work and dedication with my classmates to learn and impliment everything we were taught in the Automation course. We used Terraform to provision Azure resources and Ansible to configure the Linux VMs. The project was a great learning experience and helped us understand the importance of Infrastructure as Code (IaC) and automation in the DevOps world.

Github Repo ↗

Additional Videos

Terraform Configuration

This repository comprises of numerous Terraform sub-modules for provisioning different resources. These sub-modules are meant to be used in combination within a root module that will result in a full deployment infrastructure.

Child Module: Resource Group

The rgroup-RandomID module creates 1 resource group named RandomID-RG. It provides the name of the resource group back to the root module.

Child Module: Networking

The network-RandomID module provisions 1 virtual network known as RandomID-VNET and one subnet identified as RandomID-SUBNET under the RandomID-RG resource group. It additionally configures a network security group with four inbound access rules on ports 22, 3389, 5985, and 80. This security group is linked to the said subnet. The parent (root) module receives both names of virtual network and subnet from this module.

Child Module: Common Services

The common-RandomID module provisions one Log Analytics workspace, one Recovery services vault and one Standard storage account with LRS redundancy. Make sure that you don't use this storage account which has been created as your Terraform backend. Lastly, it returns the names of all three resources to the root module after provision is complete

Child Module: Linux Virtual Machines

vmlinux-RandomID module provisions three CentOS 8.2 Linux VMs, each located in three different availability zones and having public IP addresses. All the VMs use the storage account blob container created above for boot diagnostics of their OSes as well as data disks. There are unique DNS labels assigned to these VMs, and they have respectively installed Network Watcher and Azure Monitor extensions. Hostnames, Domain names, private IP addresses and public IP address of the VMs are returned back to root modules.

Child Module: Data Disks

Each of the four VMs is provisioned with 4 x 10GB disks by datadisk-RandomID module.

Child Module: Load Balancer

There is a single public-facing basic load balancer behind which all the three Linux VMs have been provisioned through loadbalancer-RandomID module. The name of load balancer is returned back to root module.

Child Module: Database

The database-RandomID module creates one Azure DB for PostgreSQL Single Server instance whose name is given back to parent/root module.

Root Module: Assignment1-RandomID

All child modules are defined in this assignment1-RandomID root module. When deployed successfully, it prints outputs from child modules using terraform_script.sh script file provided above

Ansible Configuration

The Ansible part of the project includes a structured approach to configure and manage the infrastructure provisioned by Terraform. Here is an overview of the Ansible configuration and roles used for this project.

Ansible Configuration

  • ansible.cfg: Main configuration file setting default behaviors like inventory source, role path, and disabling host key checking.
  • hosts: Inventory file defining the hosts and groups for Ansible to target, including specific variables such as ansible_user and ansible_connection.

Playbook: n01537188-playbook.yaml

This playbook outlines the automation steps for configuring Linux VMs. It includes pre-tasks for initial setup, roles for specific configurations, and post-tasks to conclude the automation.


  • datadisk-n01537188: Configures additional data disks by creating partitions, formatting them, and mounting them at specified locations.
  • profile-n01537188: Updates the /etc/profile file for all users with custom environmental variables and session timeout settings.
  • user-n01537188: Manages user accounts and groups, ensuring SSH keys are set up for remote access and configuring sudo privileges without a password for the cloudadmins group.
  • webserver-n01537188: Installs and configures Apache web server, deploys a basic webpage, and ensures the service is enabled and running.

Script: script.sh

A simple bash script to run the Ansible playbook, making it easy to execute the configuration steps from a command line.

Instructions for Running Ansible

  1. Ensure Ansible is installed on your system.
  2. Navigate to the Ansible directory within the project.
  3. Run the script.sh script to execute the Ansible playbook.

This approach ensures a seamless, automated configuration of the Linux VMs, complementing the infrastructure deployment done with Terraform.



Install Ansible

sudo apt update
sudo apt install ansible

Test the playbook

ansible-playbook  --verbose n01537188-playbook.yaml


Initialize the Terraform configuration

terraform init

Validate the Terraform configuration

terraform validate

Plan the Terraform configuration

terraform plan

Apply the Terraform configuration

terraform apply

Destroy the Terraform configuration

terraform destroy

Get number of resources to be created

terraform plan -detailed-exitcode