Sign in
Menu
Sign up
Docs
Adopt in an existing estate

Compliance starter kits

For a team building new AWS infrastructure that has to meet one framework from the first apply. Each kit is a standalone Terraform configuration of compliance.tf modules, wired for one framework, that you clone and own. Pick the kit for your framework below, create the shared prerequisites on this page, then follow the kit's own page to deploy.

Pick one

KitUse whenFramework and registry hostRepository
B2B SaaS - SOC 2An enterprise deal waits on a security questionnaire or a SOC 2 reportSOC 2, soc2.compliance.tfcompliancetf/starter-kit-saas-soc2
Fintech - PCI DSS v4.0You handle cardholder data now or soon; the cardholder data environment (CDE) segmentation you choose early is hard to undoPCI DSS v4.0, pcidss.compliance.tfcompliancetf/starter-kit-fintech-pcidss
HealthTech - HIPAAYou are about to handle protected health information (PHI) for the first time; RDS encryption has to be on when the database is createdHIPAA, hipaa.compliance.tfcompliancetf/starter-kit-healthtech-hipaa

Need SOC 2 as well as PCI DSS or HIPAA? Start with the kit for the stricter framework. Neither the Fintech nor the HealthTech kit ships a SOC 2 control mapping; the B2B SaaS kit has the criterion-by-criterion table, and most of its modules appear in the other two kits.

Before you start

Every kit needs these. Each kit page lists what it needs on top.

  • A compliance.tf account whose plan includes the kit's framework; see Plans and entitlements. Log in to the kit's registry host with terraform login, as in Get started.
  • Terraform or OpenTofu at a version every module in the kit accepts: the highest required_version among them. Compatibility with terraform-aws-modules explains how to check.
  • AWS credentials for the target account and a Route 53 hosted zone for the kit's domain.
  • An S3 replication role and a destination bucket in a second region. Every kit replicates its S3 buckets, so each asks for s3_replication_role_arn and s3_replication_destination_bucket_arn. The kits do not create them, because both usually live in another account or another state file. Create them as below.
  • CloudTrail, enabled at the account level. No kit creates it, because a trail is account-wide rather than part of a module, and every framework's auditor expects the AWS control plane trail. See the AWS CloudTrail documentation.

Create the replication role and destination bucket

Versioning must be on for both buckets of a replication pair. The kits' source buckets have it, because a control enforces it; the destination bucket you create here needs it too, or S3 refuses the replication configuration. This is the same-account, second-region case. A cross-account destination also needs a provider for the destination account, a destination bucket policy for the replication role and, with KMS, a destination key policy; see the AWS cross-account replication walkthrough.

Apply this in your DR region, in a configuration outside the kit:

provider "aws" {
  alias  = "dr"
  region = "us-west-2"
}

resource "aws_s3_bucket" "replica" {
  provider = aws.dr
  bucket   = "myapp-dr-us-west-2"
}

resource "aws_s3_bucket_versioning" "replica" {
  provider = aws.dr
  bucket   = aws_s3_bucket.replica.id

  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_iam_role" "replication" {
  name = "s3-replication"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "s3.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy" "replication" {
  role = aws_iam_role.replication.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["s3:GetReplicationConfiguration", "s3:ListBucket"]
        Resource = "arn:aws:s3:::myapp-*"
      },
      {
        Effect   = "Allow"
        Action   = ["s3:GetObjectVersionForReplication", "s3:GetObjectVersionAcl", "s3:GetObjectVersionTagging"]
        Resource = "arn:aws:s3:::myapp-*/*"
      },
      {
        Effect   = "Allow"
        Action   = ["s3:ReplicateObject", "s3:ReplicateDelete", "s3:ReplicateTags"]
        Resource = "${aws_s3_bucket.replica.arn}/*"
      }
    ]
  })
}

The source-side statements use an arn:aws:s3:::myapp-* wildcard because the kit's buckets do not exist yet when you create the role. Replace myapp with the project_name you set in terraform.tfvars, and narrow the wildcard to the exact bucket names after the kit's first apply.

Then pass the two ARNs to the kit in terraform.tfvars:

s3_replication_role_arn               = "arn:aws:iam::123456789012:role/s3-replication"
s3_replication_destination_bucket_arn = "arn:aws:s3:::myapp-dr-us-west-2"

Every kit encrypts its buckets with KMS (SOC 2, PCI DSS v4.0 and HIPAA all map s3_bucket_default_encryption_enabled_kms), so the replication rule and role need more than this; each kit's Before you start lists what.

Not what you need

Already running Terraform with terraform-aws-modules? Use the Migration kit: it moves existing modules to compliance.tf one at a time, without rebuilding what you have. To compose modules yourself instead of starting from a kit, browse your framework's registry host, such as soc2.compliance.tf, for each module's versions, inputs and outputs.

On this page

Ask AI about this

Help improve this page