Skip to main content

Infrastructure as Code

Terraform on AWS

Deploy AWS infrastructure reliably with Terraform — Stacks, ephemeral values, provider-defined functions, Test Framework, and OpenTofu state encryption for teams that need an OSI-licensed alternative.

Last updated:April 29, 2026Author:FactualMinds Cloud Integration TeamReviewed by:FactualMinds AWS-certified architects (Solutions Architect – Professional)

AI & assistant-friendly summary

This section provides structured content for AI assistants and search engines. You can cite or summarize it when referencing this page.

Summary

Terraform + AWS in 2026: Stacks GA, ephemeral values, provider-defined functions, Test Framework, OpenTofu 1.8 encryption — vs CDK and CloudFormation.

Key Facts

  • Terraform + AWS in 2026: Stacks GA, ephemeral values, provider-defined functions, Test Framework, OpenTofu 1
  • 8 encryption — vs CDK and CloudFormation
  • Deploy AWS infrastructure reliably with Terraform — Stacks, ephemeral values, provider-defined functions, Test Framework, and OpenTofu state encryption for teams that need an OSI-licensed alternative
  • Ephemeral values (Terraform 1
  • Ephemeral resources (1

Entity Definitions

Bedrock
Bedrock is relevant to terraform on aws.
Lambda
Lambda is relevant to terraform on aws.
S3
S3 is relevant to terraform on aws.
RDS
RDS is relevant to terraform on aws.
DynamoDB
DynamoDB is relevant to terraform on aws.
CloudFront
CloudFront is relevant to terraform on aws.
CloudWatch
CloudWatch is relevant to terraform on aws.
IAM
IAM is relevant to terraform on aws.
VPC
VPC is relevant to terraform on aws.
EKS
EKS is relevant to terraform on aws.
Glue
Glue is relevant to terraform on aws.
Secrets Manager
Secrets Manager is relevant to terraform on aws.
AWS Secrets Manager
AWS Secrets Manager is relevant to terraform on aws.
Parameter Store
Parameter Store is relevant to terraform on aws.
CodeBuild
CodeBuild is relevant to terraform on aws.
Ask AI: ChatGPT Claude Perplexity Gemini

Terraform on AWS in 2026

Terraform is still the default IaC tool on AWS for enterprise teams. What changed over the last two years is (a) Terraform Stacks going GA on HCP Terraform, (b) ephemeral values and ephemeral resources finally removing plaintext secrets from state files, (c) provider-defined functions cleaning up a lot of HCL gymnastics, (d) a production-ready Test Framework, and (e) OpenTofu maturing as a credible OSI-licensed alternative with client-side state encryption.

This page is a working guide to the 2026 configuration we ship.

Licensing in one paragraph: Terraform moved from MPL 2.0 to the Business Source License (BUSL 1.1) in August 2023. IBM completed its acquisition of HashiCorp in early 2025; Terraform and HCP Terraform continue under the HashiCorp brand inside IBM Software. OpenTofu is the Linux Foundation / CNCF fork on MPL 2.0 — functionally compatible with Terraform for most AWS workflows, increasingly diverging on advanced features (Stacks, Sentinel). Pick based on license policy, HCP usage, and roadmap needs.

What’s new for Terraform on AWS in 2026

Why Terraform on AWS

Account and state architecture (landing-zone first)

Core Terraform concepts (refresher)

Example: remote state with S3-native locking

terraform {
  required_version = ">= 1.10"

  backend "s3" {
    bucket       = "acme-prod-tfstate"
    key          = "platform/eks/terraform.tfstate"
    region       = "eu-west-1"
    encrypt      = true
    kms_key_id   = "arn:aws:kms:eu-west-1:111122223333:key/…"
    use_lockfile = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

Example: ephemeral value for a bootstrap password

ephemeral "random_password" "bootstrap" {
  length  = 32
  special = true
}

resource "aws_secretsmanager_secret_version" "initial" {
  secret_id     = aws_secretsmanager_secret.db.id
  secret_string = ephemeral.random_password.bootstrap.result
  lifecycle {
    ignore_changes = [secret_string]
  }
}

The generated password exists during the apply, writes into Secrets Manager, and is then gone — not in state, not in the plan, not in logs.

Example: provider-defined function

locals {
  arn_parts = provider::aws::arn_parse(aws_s3_bucket.this.arn)
  account_id = local.arn_parts.account_id
}

No more regexes over ARNs.

Terraform Stacks (HCP Terraform)

Use when you have three or more coupled configurations deploying together. For single-state workloads, plain workspaces are still fine.

Test Framework

# tests/s3.tftest.hcl
run "s3_bucket_is_private" {
  command = plan

  assert {
    condition     = aws_s3_bucket_public_access_block.this.block_public_acls == true
    error_message = "S3 bucket must block public ACLs"
  }

  assert {
    condition     = aws_s3_bucket_server_side_encryption_configuration.this.rule[0].apply_server_side_encryption_by_default.sse_algorithm == "aws:kms"
    error_message = "S3 bucket must be encrypted with KMS"
  }
}

Run in CI on every PR. Pair with tflint, tfsec / checkov, and Sentinel (HCP) or OPA.

OpenTofu 1.8+

Adopt OpenTofu when OSI licensing is non-negotiable or you want client-side state encryption today.

Terraform vs AWS CDK vs CloudFormation (quick matrix)

DimensionTerraformAWS CDKCloudFormation / SAMPulumi
LanguageHCLTS / Python / Java / .NET / GoYAML / JSONTS / Python / Go / .NET
ScopeMulti-cloudAWS-only (CloudFormation under the hood)AWS-onlyMulti-cloud
StateExternal (S3 / HCP)CloudFormationCloudFormationExternal
Policy engineSentinel / OPACustom AspectsCloudFormation GuardCrossGuard / OPA
Drift detectionterraform planCloudFormation DriftCloudFormation Driftpulumi preview
EcosystemLargestGrowingNative AWS coverageGrowing
Good fitEnterprise multi-cloud, HCP governanceAWS-only dev teams wanting TypeScriptMinimal-tooling AWS shopsTeams wanting CDK-style with multi-cloud

Failure modes & resilience

1. AWS provider rate limits / throttling. hashicorp/aws calls the AWS API like any other client; large apply runs hit Throttling, RequestLimitExceeded, or TooManyRequestsException on Organizations, IAM, and Lambda APIs. Configure exponential backoff via max_retries and split monolithic state files:

provider "aws" {
  region      = var.aws_region
  max_retries = 25 # default 25; bump only for known burst-heavy workloads
  default_tags {
    tags = local.common_tags
  }
}

For Organizations / Control Tower management, throttle parallelism: terraform apply -parallelism=5 (default 10). Apply runs against AWS Organizations APIs are particularly sensitive.

2. Partial-apply rollback. Terraform does not roll back on partial failure — the failed resource is left as-is, and state reflects what succeeded. Recovery: read the error, fix the cause, re-run apply. For the high-stakes case where you cannot tolerate forward recovery, gate apply behind a taint/untaint workflow and add prevent_destroy lifecycle blocks on critical infra (RDS, KMS keys, S3 buckets with Object Lock).

3. State corruption recovery. S3 versioning is your safety net. Recovery flow: aws s3api list-object-versions --bucket <state-bucket> --prefix <key> → identify last-good version → aws s3api copy-object → re-acquire lock → terraform refresh. KMS-CMK rotation does NOT impact existing state reads (KMS retains old material for decrypt) but rotating to a new key alias requires re-encrypting state via terraform init -reconfigure.

4. Drift between console and state. Inevitable in regulated multi-team accounts. Run nightly terraform plan -detailed-exitcode in CI; non-zero exit means drift. Auto-import via terraform plan -generate-config-out= (1.5+) for known-safe drift; ticket the rest.

5. Provider major-version upgrades. hashicorp/aws v5→v6 changed default behavior on several resources (aws_s3_bucket_versioning, aws_lb defaults). Always test in a staging account; use ~> 6.0 to allow patch upgrades only.

6. Cross-region operations. aws_route53_record, ACM certs in us-east-1 for CloudFront, and aws_s3_bucket_replication_configuration need provider aliases. Forgetting an alias silently creates resources in the default region.

Multi-region rollout with Stacks

# stack.tfdeploy.hcl
deployment "us_east_1" {
  inputs = { region = "us-east-1", weight = 100 }
}

deployment "eu_west_1" {
  inputs = { region = "eu-west-1", weight = 100 }
  depends_on = [deployment.us_east_1]
}

orchestrate "rolling" {
  check {
    condition = context.plan.changes.add < 50
    reason    = "Plan changed too many resources; manual review required."
  }
}

Stacks deployments run sequentially with explicit depends_on; orchestration checks gate progression. For wave-based rollouts across many regions, group deployments into waves with manual approval gates between them.

Observability runbook

CI signals:

SignalAction
Nightly terraform plan exit code 2 (drift)Auto-create ticket; review before next deploy; terraform import if benign
apply duration > 30 minSplit state; check for aws_route53_* deletes (slow), ASG drains, RDS modifications
Throttling / RateExceeded in plan/apply logsReduce -parallelism, bump max_retries, split state, request limit increase
HCP Terraform run failure rate > 5%Investigate Sentinel policy regressions, provider version skew
State lock held > 1 hrterraform force-unlock <lock-id> only after confirming no active apply in CI logs

Drift alarm wiring (CloudWatch Logs → Metric Filter → Alarm):

aws logs put-metric-filter \
  --log-group-name "/aws/codebuild/terraform-drift" \
  --filter-name terraform-drift-detected \
  --filter-pattern '"Plan: " "to add" "to change" "to destroy"' \
  --metric-transformations metricName=DriftCount,metricNamespace=Terraform,metricValue=1

Then alarm on Terraform/DriftCount > 0 and route to PagerDuty / Slack.

Common pitfalls (field-tested)

When Terraform is NOT the best fit

Stacks GA
Coordinated multi-configuration deployments on HCP Terraform
Ephemeral
Values and resources that never hit state (1.10+)
OpenTofu
1.8+ adds client-side state encryption and early resources

Tools & Calculators

Self-serve calculators and assessments that pair with this integration.

AWS Architecture Review

Get a senior AWS review of your Terraform module design and account structure.

Related AWS Services

Consulting engagements that frequently pair with this integration.

AWS Well-Architected Review — Free Assessment

Free AWS Well-Architected Review from FactualMinds. Identify risks, compliance gaps, and optimization opportunities.

AWS DevOps Consulting

AWS DevOps consulting — CI/CD pipeline setup, infrastructure as code (SAM/CDK), and deployment automation.

AWS Application Modernization — From Legacy to Cloud-Native

AWS application modernization — legacy migration, microservices, containers. Expert consulting from FactualMinds.

Who typically runs this integration?

The roles that most often own or review this stack.

AWS Solutions for DevOps & Platform Engineers

EKS Auto Mode, OIDC-native CI/CD, supply-chain security, CDK Toolkit v2, and eBPF observability for platform teams building the platform on AWS in 2026.

AWS Solutions for CTOs

Cloud strategy, multi-account governance, agentic AI platform decisions, and FinOps culture for technology leaders scaling AWS in 2026 and beyond.

Related Integrations

Other AWS integration guides commonly deployed alongside this one.

GitHub Actions with AWS

GitHub Actions to AWS in 2026: OIDC keyless auth, Artifact Attestations, Immutable Actions, ARM runners, and reusable workflows to ECS, Lambda, EKS.

Kubernetes on AWS (EKS)

Amazon EKS in 2026: Auto Mode GA, Hybrid Nodes, Karpenter 1.0, Pod Identity, Graviton-first node pools, and ECR enhanced scanning — cheaper, safer K8s.

HashiCorp Vault on AWS

HashiCorp Vault on AWS: dynamic DB credentials, transit-engine encryption, HCP Vault Secrets, and EKS Secrets Operator vs AWS Secrets Manager guidance.

Frequently Asked Questions

What is Terraform Stacks and when should I adopt it?
Terraform Stacks (GA on HCP Terraform in 2025) is a deployment model for coordinating multiple Terraform configurations as one unit — think "VPC + EKS + app + data tier across four environments and three regions" deployed through one orchestration instead of seven independently wired workspaces. It replaces a lot of the glue code teams write around `terraform_remote_state`, wrapper scripts, and CI fan-outs. Adopt it when (a) you manage more than two or three logical layers that deploy together, (b) you fan out across accounts/regions, and (c) you are already on HCP Terraform. For small teams on one workspace, plain workspaces + modules remain simpler.
What are ephemeral values and ephemeral resources?
Ephemeral values (Terraform 1.10+) are references that exist only during a plan or apply and never land in state — ideal for short-lived secrets (a rotating DB password fetched from Vault or Secrets Manager, a temporary token, a bootstrap password). Ephemeral resources (1.11+) extend the same idea to provider-defined data sources — they are materialized, used, and discarded in one run. Use them everywhere you were previously using `sensitive = true` + state encryption as a workaround; it is the first real fix for "my plaintext password is in `terraform.tfstate`".
What are provider-defined functions and what do they replace?
Provider-defined functions (Terraform 1.8+) let providers ship HCL functions alongside resources and data sources — e.g., `provider::aws::arn_parse(...)`, or parsing / formatting helpers inside the AWS / GCP / Vault providers. They replace brittle patterns like `regex(...)` gymnastics, stringly-typed helpers, and external `data` sources written just to do string manipulation. Terraform 1.9+ added `templatestring` and other native improvements; 1.10+ brought ephemeral values; 1.11+ continues the trend. Keep Terraform on a recent minor — the ergonomics wins are real.
Is the Terraform Test Framework production-ready in 2026?
Yes, for module-level unit and integration tests. `terraform test` (Terraform 1.6+, matured through 1.10+) is how we verify module invariants in CI: plan-only tests run fast and cover security rules (no public S3, encryption on, least privilege); apply-tests spin up ephemeral resources in a sandbox account and verify end-to-end. Combine with `tflint`, `checkov` / `tfsec`, and Sentinel or OPA for policy. The weak spots are long-running infra (databases, Kubernetes clusters) — those still benefit from dedicated Terratest/Go-based harnesses. For most everyday modules, the native framework is enough.
Should I stay on Terraform or move to OpenTofu in 2026?
Depends on three questions. (1) **Are you bound by an OSI-only or CNCF-only policy?** Then OpenTofu (MPL 2.0, Linux Foundation) is the pragmatic choice. OpenTofu 1.8 added client-side state encryption, 1.9 and 1.10 continued to track Terraform features where feasible. (2) **Do you rely on HCP Terraform / Sentinel / Stacks?** Stay on Terraform — Stacks in particular is not on OpenTofu's roadmap in the same form. (3) **Do you want a single provider ecosystem and minimal supply-chain friction?** Both share the same providers (OpenTofu has its own registry + ability to consume the Terraform registry) and both work with `hashicorp/aws`. Many enterprises run both: HCP Terraform for production golden-path, OpenTofu for greenfield or open-source-restricted contexts.
What changed with the IBM + HashiCorp acquisition?
IBM completed its acquisition of HashiCorp in early 2025. Practically, nothing in the CLI or AWS provider has meaningfully changed for users — Terraform and HCP Terraform remain under HashiCorp branding inside IBM Software. The BUSL 1.1 license on Terraform core remains in effect; the OpenTofu fork continues as the OSI-licensed alternative. IBM's Cloud Paks and Red Hat Ansible ecosystem have closer integration stories (ansible-terraform operators, HCP Terraform on Red Hat OpenShift), but the core AWS experience is unchanged. Watch the roadmap for deeper Watson / GenAI features in HCP Terraform over the next year.
How should I organize Terraform state and AWS accounts in 2026?
Landing zone first: AWS Control Tower + Organizations + IAM Identity Center. One AWS account per environment (dev/test/stage/prod) per workload, or per business unit + environment — not "one AWS account for everything". One Terraform state key per (account, workload); remote state in an S3 bucket inside that account with KMS CMK encryption, Block Public Access, Object Lock where required, and S3-native locking (Terraform 1.10+) or a DynamoDB table on older versions. Never share a state file across accounts; use `terraform_remote_state` data sources or — better — Terraform Stacks for cross-workspace references.
Terraform vs AWS CDK vs CloudFormation in 2026 — which should I pick?
Short version. **Terraform**: pick for multi-cloud, large existing module ecosystem, HCP Terraform policy/governance, and teams comfortable with HCL. **AWS CDK**: pick for AWS-only shops that want to write infra in TypeScript/Python, for tight integration with AWS-managed constructs, and where you want to share libraries with application code. CloudFormation under the hood. **CloudFormation / SAM**: pick for AWS-only shops that want the lightest-weight tooling, native drift detection, and ChangeSets. **Pulumi** is a fourth option if you want a CDK-like programming model with multi-cloud. Most of our enterprise customers converge on Terraform for landing-zone and cross-workload infra, with selective CDK for highly AWS-native services (Lambda packaging, CDK Pipelines, Amplify).
How do I handle secrets in Terraform on AWS?
Three rules. (1) Never hard-code secrets in HCL. (2) Source short-lived secrets with ephemeral values — pull from AWS Secrets Manager, HashiCorp Vault, or Parameter Store at plan/apply time, and let them expire after the run. (3) For long-lived generated secrets (initial DB password, KMS-wrapped values), generate inside AWS (`aws_secretsmanager_secret_version` with `random_password`) and store only an ARN reference in state. Combine with S3 state encryption via KMS CMK and OpenTofu 1.8+ client-side state encryption if your threat model requires zero-plaintext-secrets-at-rest.

Related Reading

Need Help with This Integration?

Our AWS-certified engineers can design, implement, and operate this integration end-to-end — or review what you already have.