IaC Bazaar
AWSLive-tested

EC2 Instance

EC2 instance with IMDSv2, encrypted EBS, instance profile, and EIP — secure defaults out of the box.

terraformAWS#aws

Compare Virtual Machines across clouds →

aws-ec2-instanceterraform v1.7

Verification

Live-tested

Really deployed, verified, idempotent and destroyed in a cloud sandbox.

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan: findings disclosed (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live-tested — applied, verified, destroyed

Last verified 2026-06-19 · how we verify

Documentation

aws-ec2-instance — EC2 Instance

EC2 instance with IMDSv2, encrypted EBS, instance profile, and EIP — secure defaults out of the box. IMDSv2 is enforced (http_tokens = required), the root volume and any data volumes are always encrypted (gp3 by default), and the module ships an SSM-agent-ready instance profile so you get Session Manager shell access with zero SSH keys and zero inbound ports. AMI defaults to the latest Amazon Linux 2023 for your architecture (Graviton arm64 by default).

Works with Terraform and OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.

Usage

module "app_server" {
  source = "./aws-ec2-instance"

  name                   = "app-1"
  instance_type          = "t4g.small" # Graviton; set architecture = "x86_64" for Intel/AMD types
  subnet_id              = module.vpc.private_subnet_ids[0]
  vpc_security_group_ids = [module.app_sg.security_group_id]

  data_volumes = {
    data = { device_name = "/dev/xvdf", size = 100 }
  }

  tags = { Environment = "prod" }
}

Then connect with aws ssm start-session --target <instance_id> — no bastion, no port 22.

Inputs

NameTypeDefaultDescription
namestringName for instance + derived resources (required)
subnet_idstringTarget subnet (required)
vpc_security_group_idslist(string)≥ 1 security group (required)
ami_idstringnullExplicit AMI; null = latest AL2023 lookup
architecturestring"arm64"AMI lookup arch (arm64/x86_64); must match instance type
instance_typestring"t4g.small"Instance type
associate_public_ip_addressboolfalseEphemeral public IP at launch
create_eipboolfalseStable Elastic IP + association
private_ipstringnullStatic primary private IP
source_dest_checkbooltrueDisable only for NAT/router instances
key_namestringnullSSH key pair (usually unnecessary with SSM)
user_datastringnullCloud-init user data
user_data_replace_on_changeboolfalseRecreate instance on user_data change
create_instance_profilebooltrueCreate role + instance profile
instance_profile_namestringnullExisting profile when not creating one
enable_ssmbooltrueAttach AmazonSSMManagedInstanceCore
additional_policy_arnsset(string)[]Extra policies for the module-managed role
metadata_http_put_response_hop_limitnumber1IMDSv2 hop limit (2 for containers)
enable_instance_metadata_tagsboolfalseExpose tags via IMDS
monitoringboolfalseDetailed CloudWatch monitoring
ebs_optimizedbooltrueEBS-optimized launch
enable_termination_protectionboolfalsedisable_api_termination for pet instances
root_volume_sizenumber20Root volume GiB
root_volume_typestring"gp3"gp3/gp2/io1/io2
root_volume_iops / root_volume_throughputnumbernullgp3/io* tuning
kms_key_arnstringnullCMK for EBS; null = AWS-managed key (encryption always on)
data_volumesmap(object){}Extra encrypted volumes: { device_name, size, type?, iops?, throughput?, kms_key_arn? }
tagsmap(string){}Tags applied to all resources

Outputs

NameDescription
instance_id, instance_arn, availability_zoneInstance identifiers
private_ip, public_ipAddresses (public_ip prefers the EIP)
eip_allocation_idEIP allocation (null if disabled)
primary_network_interface_idPrimary ENI
ami_idEffective AMI used
iam_role_name, iam_role_arn, instance_profile_nameIAM wiring
data_volume_idsLogical name => volume ID map

Notes

  • The AL2023 lookup pins nothing: each plan resolves the latest AMI, which can replace the instance on a new release. Pin ami_id for fleets that must not drift.
  • Graviton (arm64) is the default for price/performance; set both architecture = "x86_64" and an x86 instance_type together.

Requirements

  • Terraform or OpenTofu >= 1.6
  • hashicorp/aws >= 6.0, < 7.0

Verification

Static-validated (fmt, validate, tflint). Live apply/destroy testing pending cloud sandbox availability — see catalog status.

License

Commercial — IaC Bazaar EULA. © IaC Bazaar. Original work (not derived from a third-party module).