> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fastfoundation.nimble.la/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy an EC2 instance

> Step-by-step guide to deploy an EC2 instance using the terraform-aws-modules/ec2-instance module with Terragrunt

<Warning>
  This workshop assumes you’re already familiar with the techniques and concepts in the  **Introduction & Key Concepts** section. If you haven’t reviewed it yet, start with [AWS Architecture](/introduction-key-concepts/1-aws-architecture) and work your way through the rest of the section to fully understand the mechanics and philosophy behind our setup.
</Warning>

## Prerequisites

<Check>
  * AWS SSO signed in: `aws sso login --profile <your-profile>`. See [Getting Started with AWS SSO](/aws-sso/1-getting-started-with-aws-single-sign-on-sso) if you need help setting this up
  * Fast Foundation **infrastructure repository** cloned
  * You know the **target account / environment / region** you'll deploy to
  * You have a **VPC** and at least one **subnet** ready (private subnet recommended)
</Check>

***

## Target folder (where to place your unit)

<Warning>
  If your ec2 folder did not exist, add an empty ".../ec2/\_service.hcl" file with content

  ```
  locals {
    service = basename(get_terragrunt_dir())
  }
  ```
</Warning>

Pick the account, environment, and region. Example path for a dev workload:

```
fast-foundation-infrastructure/
└── Workloads/
    └── Development/
        └── <development_workload_account>/
            └── development
                └── <your_region>/
                    └── ec2/
                        └── _service.hcl
                        └── web-ec2/
                            ├── terragrunt.hcl
                            └── inputs.hcl
```

***

## Step 1 — Create `terragrunt.hcl`

This references the **official module** from the Terraform Registry.

<CodeGroup>
  ```hcl terragrunt.hcl theme={null}
  terraform {
    # Use the official module directly (no wrapper)
    source = "tfr://registry.terraform.io/terraform-aws-modules/ec2-instance/aws?version=5.8.0"
  }

  include "root" {
    path   = find_in_parent_folders("root.hcl")
    expose = true
  }

  locals {
    # Shared Configurations
    region_vars          = include.root.locals.region_vars.locals
    service_vars         = include.root.locals.service_vars.locals
    environment_vars     = include.root.locals.environment_vars.locals

    # Unit Inputs from inputs.hcl
    inputs = try(read_terragrunt_config("${get_terragrunt_dir()}/inputs.hcl").locals, {})
    
    # Use folder name for a friendly resource name
    instance_name = basename(get_terragrunt_dir())
  }

  inputs = {
    # Minimal set for the module to launch an instance
    name          = basename(get_terragrunt_dir())            #Naming best practice
    instance_type = try(local.inputs.instance_type, "t3.micro")
    monitoring = try(local.inputs.monitoring, false)
    # key_name = try(local.inputs.key_name, "my-keypair")
    
    # Reference VPC from parameter store
    vpc_security_group_ids = [try(local.inputs.security_group_id, "sg-1234567890abcdef")]
    subnet_id = try(local.inputs.subnet_id, "subnet-1234567890abcdef")
    region = try(local.region_vars.region, "us-west-2")  
    
    tags = {
      Environment = try(local.environment_vars.environment, "development")
      Name = basename(get_terragrunt_dir()) 
      Instance = local.instance_name
      DeployedBy = "terragrunt"
    }
  }
  ```
</CodeGroup>

***

## Step 2 — Define `inputs.hcl`

Parameter values are stored in Git. Example for development:

<CodeGroup>
  ```hcl inputs.hcl theme={null}
  locals {
    instance_type = "t3.micro"
    subnet_id = "subnet-1234567890abcdef"  # Replace with a valid subnet ID
    security_group_id = "sg-1234567890abcdef"  # Replace with a valid security group ID
    monitoring = false
  }
  ```
</CodeGroup>

***

## Step 3 — Deploy the instance

Run these commands from your new folder:

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

***

## What you learned

* How to **use the official EC2 module directly** with Terragrunt

***

## Cleanup

<Warning>
  **Important**: Don't forget to clean up the resources you created during this workshop to avoid unnecessary AWS charges.
</Warning>

To destroy the EC2 instance and all associated resources, run the following command from your deployment folder:

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

When prompted, type `yes` to confirm the destruction of resources.

***

<NextSteps>
  Try extending this setup:

  * Add a security group with HTTP ingress
  * Attach an Elastic IP
  * Or practice with dependencies by pulling VPC/subnet IDs dynamically
</NextSteps>
