> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setting Up the Third Group of Resources EC2

> Provisioning reusable Terraform EC2 module and Terragrunt environment configurations to deploy and manage EC2 instances across dev and prod with best practices and deployment steps

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."](https://mintcdn.com/kodekloud-c4ac6d9a/guoie6wQNxAcGKSL/images/Terragrunt-for-Beginners/Building-our-first-AWS-Demo-with-Terragrunt/Setting-Up-the-Third-Group-of-Resources-EC2/terraform-terragrunt-ec2-module-tree.jpg?fit=max\&auto=format\&n=guoie6wQNxAcGKSL\&q=85\&s=39f2a8d53cebec8b8ae6d8b774500cf1)

## 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:

```hcl theme={null}
terraform {
  source = "../../../modules/ec2"
}

inputs = {
  name                = "web-server-dev"
  instance_type       = "t3.micro"
  ami                 = "ami-0abcdef1234567890" # replace with a region-correct AMI
  key_name            = "my-ssh-key"
  subnet_id           = "subnet-0123456789abcdef0"
  security_group_ids  = ["sg-0123456789abcdef0"]
  tags = {
    Environment = "dev"
    Project     = "demo"
  }
}
```

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:

```hcl theme={null}
variable "name" {
  type        = string
  description = "Name tag for the instance"
}

variable "instance_type" {
  type        = string
  description = "EC2 instance type"
  default     = "t3.micro"
}

variable "ami" {
  type        = string
  description = "AMI ID to use for the instance"
}

variable "key_name" {
  type        = string
  description = "Existing EC2 key pair name for SSH access"
  default     = ""
}

variable "subnet_id" {
  type        = string
  description = "Subnet ID for the instance"
}

variable "security_group_ids" {
  type        = list(string)
  description = "List of security group IDs to attach to the instance"
  default     = []
}
```

For quick reference, here is a summary table for these variables:

| Variable | Type | Description | Default |
| - | - | - | - |
| `name` | `string` | Name tag for the instance | (none) |
| `instance_type` | `string` | EC2 instance type | `t3.micro` |
| `ami` | `string` | AMI ID for the instance | (none) |
| `key_name` | `string` | EC2 key pair name (for SSH) | `""` |
| `subnet_id` | `string` | Subnet ID to launch the instance in | (none) |
| `security_group_ids` | `list(string)` | Security group IDs attached to the instance | `[]` |

## Deployment steps with Terragrunt

1. Change directory to the target environment folder (for example `live/account/dev/third-group`).
2. Initialize the configuration:

```bash theme={null}
terragrunt init
```

3. Preview the planned changes:

```bash theme={null}
terragrunt plan
```

4. Apply the configuration to create resources:

```bash theme={null}
terragrunt apply
```

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.](https://mintcdn.com/kodekloud-c4ac6d9a/guoie6wQNxAcGKSL/images/Terragrunt-for-Beginners/Building-our-first-AWS-Demo-with-Terragrunt/Setting-Up-the-Third-Group-of-Resources-EC2/ec2-resources-terragrunt-deployment-considerations.jpg?fit=max\&auto=format\&n=guoie6wQNxAcGKSL\&q=85\&s=9cdaf6cef88c7adf55830c7ec7b6ebe3)

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

* Proceed to the [AWS For Beginners with Hands-On Labs](https://learn.kodekloud.com/user/courses/aws-for-beginners-with-hands-on-labs) to set up a full demo project and apply these patterns.
* References:
  * Terragrunt docs: [https://terragrunt.gruntwork.io/](https://terragrunt.gruntwork.io/)
  * Terraform EC2 resource: [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance)

> **[Watch Video](https://learn.kodekloud.com/user/courses/terragrunt-for-beginners/module/07066843-7439-443b-b2d4-d31be3c50c97/lesson/5fac8927-90e5-4ca3-b9a1-962a45bfd47a)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.