A small, working demo of Packer, Ansible, CINC Auditor (the open-source InSpec) and Terraform used together on AWS.
The end result is a "Hello World" PHP page served by nginx on a single EC2 instance in its own VPC.
- Packer builds an Amazon Machine Image (AMI).
- Ansible runs inside Packer to install nginx and PHP and configure the site.
- CINC Auditor runs inside Packer to verify the image looks the way we expect.
- Terraform creates a small VPC and launches an EC2 instance from that AMI.
Building the image with Packer, Ansible and the verification checks:
Deploying with Terraform:
- An AWS account, with credentials available to your shell (see below).
- Packer >= 1.7
- Terraform >= 1.0
- CINC Auditor — only if you want to run the checks outside Packer.
Or skip installing them and use the pinned toolchain image, which has matching versions of everything:
make tools-build
make shellPacker and Terraform both use the standard AWS credential chain, so set a
profile (or the usual AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY) before you
start:
export AWS_PROFILE=your-profile
export AWS_REGION=eu-west-1Use an identity that can manage EC2 and VPC resources. Prefer a least-privilege IAM role or AWS IAM Identity Center (SSO) over long-lived access keys.
cd packer
packer init .
packer validate .
packer build .This builds from the latest Ubuntu 24.04 LTS, runs the Ansible roles, and verifies the result with CINC Auditor.
cd terraform
cp terraform.tfvars.example terraform.tfvars # then set aws_account_id
terraform init
terraform applyaws_account_id is the account that owns the AMI Packer built. The instance's
public DNS is printed as an output — open it in a browser to see the page.
region— defaults toeu-west-1(or setAWS_REGION).default_instance_type— defaults tot3.micro.ssh_public_key_path— public key for the EC2 key pair, defaults to~/.ssh/id_rsa.pub.ssh_cidr— set to a CIDR to open SSH (port 22) to just that range. Empty by default, so no SSH rule is created.
Roughly $9/month to run in eu-west-1, estimated with
Infracost:
| Resource | Monthly cost |
|---|---|
EC2 instance (t3.micro, on-demand) |
$8.32 |
| Root EBS volume (8 GB) | $0.88 |
| VPC, subnets, internet gateway, route tables, security group, key pair | free |
| Total | ~$9.20 |
Usage-based costs such as data transfer aren't included, and prices vary by
region and over time. Regenerate the breakdown with make cost (needs a free
Infracost API key).
make fmt-check # terraform fmt
make validate # terraform validate
make lint # tflint + ansible-lintCI runs the same checks on every pull request. There's also a pre-commit config:
pre-commit installcd terraform
terraform destroyTo remove the AMI, deregister it from the EC2 console or with the AWS CLI.