| name | terraform-aws |
| description | Provision AWS infrastructure with Terraform including VPC, EC2, RDS, IAM, and security best practices |
| sasmp_version | 1.3.0 |
| version | 2.0.0 |
| bonded_agent | 04-terraform-aws |
| bond_type | PRIMARY_BOND |
Terraform AWS Skill
Production patterns for AWS infrastructure provisioning with security and cost optimization.
Provider Setup
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Environment = var.environment
Project = var.project
ManagedBy = "Terraform"
}
}
}
VPC Architecture
Multi-AZ VPC
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.1.2"
name = "${var.project}-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = var.environment != "prod"
one_nat_gateway_per_az = var.environment == "prod"
enable_dns_hostnames = true
enable_flow_log = true
}
Security Groups
resource "aws_security_group" "web" {
name_prefix = "${var.project}-web-"
vpc_id = module.vpc.vpc_id
lifecycle {
create_before_destroy = true
}
}
resource "aws_vpc_security_group_ingress_rule" "https" {
security_group_id = aws_security_group.web.id
from_port = 443
to_port = 443
ip_protocol = "tcp"
cidr_ipv4 = "0.0.0.0/0"
}
EC2 Instances
Launch Template + ASG
resource "aws_launch_template" "app" {
name_prefix = "${var.project}-"
image_id = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
metadata_options {
http_tokens = "required" # IMDSv2
}
block_device_mappings {
device_name = "/dev/xvda"
ebs {
volume_size = 20
volume_type = "gp3"
encrypted = true
}
}
iam_instance_profile {
arn = aws_iam_instance_profile.app.arn
}
}
resource "aws_autoscaling_group" "app" {
name = "${var.project}-asg"
desired_capacity = 2
max_size = 10
min_size = 1
vpc_zone_identifier = module.vpc.private_subnets
target_group_arns = [aws_lb_target_group.app.arn]
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
instance_refresh {
strategy = "Rolling"
preferences {
min_healthy_percentage = 75
}
}
}
IAM Best Practices
Least Privilege Role
data "aws_iam_policy_document" "assume" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "app" {
name = "${var.project}-app"
assume_role_policy = data.aws_iam_policy_document.assume.json
}
data "aws_iam_policy_document" "app" {
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:PutObject"
]
resources = ["${aws_s3_bucket.app.arn}/*"]
}
}
resource "aws_iam_role_policy" "app" {
name = "app-policy"
role = aws_iam_role.app.id
policy = data.aws_iam_policy_document.app.json
}
RDS Database
resource "aws_db_instance" "main" {
identifier = "${var.project}-db"
engine = "postgres"
engine_version = "15.4"
instance_class = "db.t3.medium"
allocated_storage = 100
max_allocated_storage = 500
storage_encrypted = true
db_name = var.db_name
username = var.db_username
password = random_password.db.result
multi_az = var.environment == "prod"
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.rds.id]
backup_retention_period = 30
deletion_protection = var.environment == "prod"
skip_final_snapshot = var.environment != "prod"
performance_insights_enabled = true
}
S3 Bucket
resource "aws_s3_bucket" "app" {
bucket = "${var.project}-${var.environment}-data"
}
resource "aws_s3_bucket_versioning" "app" {
bucket = aws_s3_bucket.app.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "app" {
bucket = aws_s3_bucket.app.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.main.arn
}
}
}
resource "aws_s3_bucket_public_access_block" "app" {
bucket = aws_s3_bucket.app.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Troubleshooting
| Error |
Cause |
Solution |
UnauthorizedAccess |
Missing IAM permissions |
Check role policies |
VPCIdNotSpecified |
VPC not provided |
Set vpc_id explicitly |
ResourceInUse |
Dependencies exist |
Check dependents first |
LimitExceeded |
Quota reached |
Request limit increase |
Usage
Skill("terraform-aws")
Related
- Agent: 04-terraform-aws (PRIMARY_BOND)