04 · Infrastructure automation

Infrastructure, Without the Repetitive Work.

Infrastructure Automation with Terraform, Ansible and Jenkins

A Jenkins pipeline that validates Terraform configuration, generates and reviews an execution plan, requires manual approval before applying changes, and verifies the resulting EC2 environment using AWS Systems Manager and Ansible.

Pipeline completed with Systems Manager-based verification

  • Terraform
  • Jenkins
  • Ansible
  • AWS EC2
  • AWS Systems Manager
  • Amazon S3
  • Nginx
View repository

01Overview and objectives

The goal was to manage AWS infrastructure through a repeatable Jenkins pipeline instead of running infrastructure commands manually.

The pipeline validates the Terraform configuration, generates a plan for review, pauses for human approval, applies the approved plan, and verifies the resulting environment.

The challenge

Running Terraform manually can make infrastructure changes harder to review and reproduce. This project introduces a controlled workflow with validation, a saved execution plan, an approval checkpoint, and post-apply verification.

02Architecture

Terraform, Jenkins and Ansible pipelineJenkins checks out the code, runs Terraform fmt and validate, saves a plan, waits for manual approval and applies the saved plan to create an EC2 instance in a security group, with encrypted S3 remote state and locking. It then starts Nginx through Systems Manager, runs Ansible syntax and health checks, and verifies Nginx through Systems Manager.PROVISIONJenkinscheckoutfmt + validateTerraformSaved planterraform planUApprovalmanual gateApplysaved plan onlyVERIFYStart NginxSystems ManagerSyntax checkAnsibleHealth checksAnsibleVerify NginxSystems ManagerFOUNDATIONSEC2 + security groupNginx hostS3 remote stateencrypted + lockingAWS credentialsJenkins credential store
Stages of the Jenkins pipeline.

The Jenkins pipeline connects infrastructure provisioning with post-apply checks, providing a repeatable workflow from planning through verification.

Infrastructure Provisioning

Checkout → Terraform formatting and validation → Generate saved plan → Manual approval → Apply saved plan

Post-Apply Verification

Start Nginx through AWS Systems Manager → Ansible syntax check → Ansible health checks → Verify Nginx through Systems Manager

03How it was built

  1. Infrastructure as code: Created Terraform configuration for EC2, a security group, and an S3 bucket.
  2. Remote state: Configured Terraform state storage in an encrypted S3 bucket with locking.
  3. Jenkins pipeline: Added stages for checkout, formatting, validation, plan generation, approval, and apply.
  4. Controlled changes: Saved the Terraform plan to a file and applied that saved plan after manual approval.
  5. Credential handling: Used the Jenkins credential store for AWS credentials instead of hardcoding them in the repository.
  6. Systems Manager verification: Ran commands on EC2 through AWS Systems Manager, polling command results with timeouts and handling unsuccessful outcomes.
  7. Ansible health checks: Added a syntax-validation stage and a playbook that checks the execution user, system uptime, root filesystem usage, and memory.

Verified in the repository

  • Terraform configuration for EC2, a security group, and an S3 bucket.
  • Encrypted S3 remote state and locking configuration.
  • Jenkins pipeline stages for validation, planning, approval, applying, and verification.
  • Systems Manager commands to start and verify Nginx on EC2.
  • Ansible playbook for Linux health checks.

04Decisions and trade-offs

Apply the Reviewed Plan

The pipeline saves the Terraform execution plan, pauses for approval, and applies the saved plan. This keeps the apply stage tied to the plan reviewed at the approval checkpoint.

Centralized Remote State

S3-based remote state provides a shared location for Terraform state, while locking helps prevent conflicting state operations.

Systems Manager Instead of SSH

AWS Systems Manager runs commands on the EC2 instance through AWS-managed infrastructure, avoiding a dependency on direct SSH access for the pipeline's verification steps.

Fail Clearly on Verification Errors

The SSM stages poll command status, capture command output, and handle failures, cancellations, and timeouts instead of waiting indefinitely.

05Security considerations

  • AWS credentials are stored in Jenkins and used by the relevant pipeline stages.
  • Manual approval is required before Terraform applies infrastructure changes.
  • Terraform state is stored in an encrypted S3 bucket with locking.
  • Systems Manager is used for instance commands rather than relying on SSH for pipeline verification.
  • The security group restricts SSH access to a designated administrator address and allows HTTP access as configured.

06Challenges and troubleshooting

Direct SSH Access Was Not Available for Pipeline Verification

Root cause
The pipeline could not rely on direct SSH access to start and check Nginx. The underlying cause of the SSH issue was not established, so no specific root cause is claimed.
Resolution
Added AWS Systems Manager command execution, result polling, and handling for command failures, cancellation, and timeouts.
Outcome
The Jenkins pipeline completed successfully using the Systems Manager-based approach.
Lesson
Systems Manager can provide a useful alternative for remote instance operations when direct SSH access is unavailable.

08Scope and next steps

This project demonstrates infrastructure provisioning through Terraform, approval-based changes through Jenkins, remote command execution through AWS Systems Manager, and Linux health checks through Ansible.

Ansible currently performs health checks on the Jenkins host. Nginx is started and verified on EC2 through Systems Manager rather than installed and configured by Ansible.

The project focuses on infrastructure automation and verification rather than a complete configuration management or production deployment platform.

Potential improvements

  • Add an Ansible role to install and configure Nginx on EC2.
  • Introduce dynamic inventory for targeting provisioned instances.
  • Add a post-deployment HTTP health check to the Jenkins pipeline.