Skip to main content
In this lesson we provision the third group of resources: EC2 instances. We’ll deploy instances across environments (for example, dev and prod) using a reusable Terraform module and Terragrunt wrappers. EC2 provides the compute layer for workloads; packaging common configuration in a module improves consistency, reduces duplication, and simplifies environment-specific overrides. We will:
  • Build a reusable Terraform module that provisions EC2 instances and exposes inputs for AMI, instance type, key pair, networking, and security groups.
  • Create a Terragrunt configuration for each environment that supplies environment-specific inputs to the module.
  • Initialize, plan, and apply the Terragrunt configuration to provision the instances.
A slide titled "Setting up the third group of resources (EC2)" showing a Terraform module icon pointing to an Amazon EC2 icon. On the right is a Terragrunt configuration tree (root → account → dev/prod with terragrunt.hcl files) with labels for "Custom Module" and "Configuration."

Architecture and layout (conceptual)

Recommended layout:
  • Create a reusable Terraform module at infrastructure/modules/ec2 that contains the EC2 resources and supporting pieces (for example aws_instance, optional aws_ebs_volume, tags, and outputs).
  • Create a Terragrunt folder per environment that references the module and injects environment-specific inputs. Example layout:
    • live/account/dev/third-group/terragrunt.hcl
    • live/account/prod/third-group/terragrunt.hcl
This separation keeps module logic generic while letting Terragrunt supply environment-specific values (names, AMIs, subnets, security groups, etc.).

Example Terragrunt configuration

A typical environment terragrunt.hcl that points at a local module:
Note: The source path must point to your module. If you publish the module to a registry or Git repository, use the appropriate source URL or registry format.

Common module variables (example)

Inside your module (infrastructure/modules/ec2/variables.tf) declare variables to accept environment inputs. Example:
For quick reference, here is a summary table for these variables:

Deployment steps with Terragrunt

  1. Change directory to the target environment folder (for example live/account/dev/third-group).
  2. Initialize the configuration:
  1. Preview the planned changes:
  1. Apply the configuration to create resources:
When running terragrunt apply, review the plan carefully before confirming. Verify the instance counts, AMI IDs, instance types, tags, and network attachments match expectations.

Key considerations (best practices)

  • Security groups: follow least-privilege principles. Avoid opening SSH (port 22) to 0.0.0.0/0 in production—restrict to known IPs or use AWS Systems Manager Session Manager.
  • Key pairs: key_name must reference an existing EC2 key pair in the selected region unless you use a different access mechanism (for example, SSM).
  • AMI IDs are region-specific: ensure the AMI exists in the target region.
  • Networking: confirm subnet_id and security_group_ids are valid for the target VPC/account.
  • IAM permissions: the AWS credentials used must have permissions to create EC2 instances, attach networking resources, and tag resources.
Before applying, confirm you are using the correct AWS profile and region. You can set these via environment variables (for example AWS_PROFILE and AWS_REGION) or in your Terragrunt/Terraform provider configuration.
A presentation slide titled "Setting up the third group of resources (EC2)" showing a folder icon with Terragrunt steps (init, plan, apply) under a "Deployment" label on the left and a shield with a checkmark under a "Considerations" label on the right.
Do not leave management ports (SSH/RDP) open to the public internet. Use restrictive security group rules or AWS Systems Manager to avoid exposing instances unnecessarily.
Resources and next steps

Watch Video