AWS — Getting Started
Prerequisites
| Requirement | Version |
|---|---|
| Terraform | ≥ 1.0.0 |
AWS provider (hashicorp/aws) | ≥ 5.0 |
| AWS CLI | Configured with target account credentials |
Provider Configuration
# versions.tf
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}
provider "aws" {
region = var.region
default_tags {
tags = {
ManagedBy = "terraform"
Environment = var.environment
}
}
}
For CI/CD — authenticate via environment variables:
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_DEFAULT_REGION="us-east-1"
# or use OIDC via terraform-aws-iam-role + AssumeRoleWithWebIdentity
Remote State (S3 + DynamoDB)
# Create the state bucket and lock table once per account
aws s3api create-bucket \
--bucket my-org-terraform-state \
--region us-east-1
aws s3api put-bucket-versioning \
--bucket my-org-terraform-state \
--versioning-configuration Status=Enabled
aws s3api put-bucket-encryption \
--bucket my-org-terraform-state \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'
aws dynamodb create-table \
--table-name terraform-state-lock \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
# backend.tf
terraform {
backend "s3" {
bucket = "my-org-terraform-state"
key = "production/networking/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}
The Labels Convention
All CloudDrove modules use terraform-aws-labels to generate consistent resource names and tags. Every module exposes the same naming variables:
| Variable | Type | Example | Description |
|---|---|---|---|
name | string | "app" | Resource name component |
environment | string | "prod" | Environment component |
label_order | list(string) | ["name","environment"] | Controls the order of name components |
managedby | string | "terraform" | Value of the ManagedBy tag |
attributes | list(string) | ["blue"] | Extra name suffixes |
delimiter | string | "-" | Separator between name components |
A resource named with name = "vpc", environment = "prod", label_order = ["name","environment"] becomes vpc-prod.
# All CloudDrove modules follow this pattern
module "vpc" {
source = "git::https://github.com/clouddrove/terraform-aws-vpc.git?ref=2.0.0"
name = "vpc"
environment = "prod"
label_order = ["name", "environment"]
managedby = "terraform"
cidr_block = "10.0.0.0/16"
}
The enable Flag
Every module has an enable (or enabled) boolean that controls whether resources are created. Useful in shared modules where some resources are conditional:
module "vpc" {
source = "git::https://github.com/clouddrove/terraform-aws-vpc.git?ref=2.0.0"
enable = var.create_vpc # set false in environments that share a VPC
name = "vpc"
environment = var.environment
cidr_block = "10.0.0.0/16"
}
Pinning Module Versions
Use ?ref= with a tag to pin:
source = "git::https://github.com/clouddrove/terraform-aws-vpc.git?ref=2.0.0"
To find available tags:
# List tags for any module
git ls-remote --tags https://github.com/clouddrove/terraform-aws-vpc.git
Passing Outputs Between Modules
CloudDrove modules are designed to chain together — outputs from one become inputs to the next:
module "vpc" {
source = "git::https://github.com/clouddrove/terraform-aws-vpc.git?ref=2.0.0"
name = "main"
environment = "prod"
cidr_block = "10.0.0.0/16"
}
module "subnets" {
source = "git::https://github.com/clouddrove/terraform-aws-subnet.git?ref=2.1.0"
name = "main"
environment = "prod"
# Chained from vpc module outputs
vpc_id = module.vpc.vpc_id
igw_id = module.vpc.igw_id
availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
type = "public-private"
ipv4_public_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
ipv4_private_cidrs = ["10.0.10.0/24", "10.0.11.0/24", "10.0.12.0/24"]
nat_gateway_enabled = true
}
module "sg" {
source = "git::https://github.com/clouddrove/terraform-aws-security-group.git?ref=2.0.0"
name = "app"
environment = "prod"
# Chained from vpc module output
vpc_id = module.vpc.vpc_id
new_sg_ingress_rules_with_cidr_blocks = {
https = {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
description = "HTTPS from internet"
}
}
}
Common Variables Reference
These variables appear in every CloudDrove AWS module:
| Variable | Default | Notes |
|---|---|---|
name | "" | Required in practice — used in resource names |
environment | "" | Required in practice — used in resource names and tags |
label_order | ["name","environment"] | Change to ["environment","name"] or add "region" |
managedby | "[email protected]" | Override with your org name |
repository | module GitHub URL | Used as a tag — override with your IaC repo |
enable / enabled | true | Set false to skip resource creation |
Reference: terraform-aws-labels →