Skip to main content

AWS — Getting Started

Prerequisites

RequirementVersion
Terraform≥ 1.0.0
AWS provider (hashicorp/aws)≥ 5.0
AWS CLIConfigured 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:

VariableTypeExampleDescription
namestring"app"Resource name component
environmentstring"prod"Environment component
label_orderlist(string)["name","environment"]Controls the order of name components
managedbystring"terraform"Value of the ManagedBy tag
attributeslist(string)["blue"]Extra name suffixes
delimiterstring"-"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:

VariableDefaultNotes
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
repositorymodule GitHub URLUsed as a tag — override with your IaC repo
enable / enabledtrueSet false to skip resource creation

Reference: terraform-aws-labels →