At AWS re:Invent? Bring your audit questions to Anton Babenko.Meet Anton at AWS re:InventAsk for a time
Sign in
Menu
Start free
Annex D: ISO 27001

ISO 27001 controls built into your Terraform modules. Enforced before apply.

Annex A technological controls ask for encryption, logging, access management and network security on AWS resources. The modules enforce these controls before apply and list the Annex A control each one maps to, where the catalog names one.

Modules enforce 93 of 166 ISO 27001 controls in the catalog. Of the 140 that cite a ISO 27001 clause, they enforce 78. The controls they do not enforce stay with your team, with your ISMS, risk treatment, internal audits and physical security.

No credit card or AWS account needed to start. By Anton Babenko, maintainer of terraform-aws-modules, more than 2 billion provisions.

Annex D: ISO 27001

Framework
ISO/IEC 27001:2022, Annex A
For
Your team, on Terraform
D.1

Scope for ISO 27001

Enterprise procurement teams, often in Europe and Asia-Pacific, ask for an ISO 27001 certificate before they sign.

D.1.1

Covers

  • Infrastructure controls on AWS resources that map to ISO/IEC 27001:2022 Annex A controls, by theme in D.3.
  • terraform-aws-modules through the ISO 27001 framework host or your org endpoint. Once your team switches to the compliance.tf provider, resources written by hand outside modules are checked against its built-in CIS controls, not the ISO 27001 set.
D.1.2

Stays with your team

  • The ISMS and its documentation.
  • Risk assessment and treatment plans (clauses 6.1 and 8.2).
  • Management reviews and internal audits (clauses 9.2 and 9.3).
  • Competence, awareness and training (clause 7.2).
  • Incident management procedures (A.5.24 to A.5.28).
  • Supplier relationship security (A.5.19 to A.5.23).
  • Physical security controls (A.7).
  • Resources outside compliance.tf module coverage, and every control D.4 lists as Mapped: 62 with a ISO 27001 clause and 11 without one.
D.2

The source line

Point a module at the ISO 27001 framework host. Same inputs and outputs, no state migration. Terraform 1.0 or later.

-  source  = "terraform-aws-modules/s3-bucket/aws"
+  source  = "iso27001.compliance.tf/terraform-aws-modules/s3-bucket/aws"
   version = "~> 5.0"

With an org endpoint, the source names your org host instead, and ISO 27001 comes from your org's configuration.

D.3

Enforced and mapped, by theme

Of the 140 ISO 27001 controls in the documented catalog that cite a clause, modules enforce 78. A control appears once under each theme it maps to.

A.875 of 129
A.53 of 11

The catalog maps 26 more controls to ISO 27001 without naming a clause, 15 of them enforced. They are listed apart at the end of D.4 and left out of these counts.

Every row is a control your auditor can look up.

Filter the register, or search by control name or clause, for example A.8.24.

140 of 140 shown

Each control links to its public docs page.

Enforced
Modules set this control before anything is deployed.
Mapped
Documented on its docs page, not set by modules. Your team owns it.
D.4

Control register

ControlStatusISO 27001 clauses
AppSync API caches should have encryption in transit enabledEnforcedA.8.24
AppSync GraphQL APIs should have field-level logging enabledEnforcedA.8.15
CloudFront distributions should have field level encryption enabledEnforcedA.8.11, A.8.24
CloudFront distributions access logs should be enabledEnforcedA.8.15, A.8.16
CloudFront distributions should use the recommended TLS security policyEnforcedA.8.24
CloudWatch log groups should have retention period of at least 365 daysEnforcedA.8.15, A.8.16
DMS replication instances should specify a KMS key for storage encryptionEnforcedA.8.24 (supporting)
DynamoDB tables should have AWS KMS encryption enabledEnforcedA.8.5, A.8.24
DynamoDB tables should have encryption enabledEnforcedA.8.5, A.8.24
Attached EBS volumes should have encryption enabledEnforcedA.8.24
EC2 instances should have IAM profile attachedEnforcedA.8.2, A.8.20, A.8.21, A.8.22
EC2 instances should not have a public IP addressEnforcedA.8.3, A.8.20, A.8.21, A.8.22
EC2 instances should use IMDSv2EnforcedA.8.20, A.8.21, A.8.22
EC2 launch templates should not assign public IPs to network interfacesEnforcedA.8.20, A.8.21, A.8.22
ECS services should not have public IP addresses assigned automaticallyEnforcedA.8.3
EFS file systems should have encryption at rest enabledEnforcedA.8.24
EKS clusters should have control plane audit logging enabledEnforcedA.8.15
EKS clusters endpoint public access should be restrictedEnforcedA.8.3
EKS clusters endpoint should restrict public accessEnforcedA.8.3
ElastiCache for Redis replication groups should have automatic failover enabledEnforcedA.8.14
ElastiCache for Redis replication groups should be encrypted at restEnforcedA.8.24
ElastiCache for Redis replication groups should be encrypted with CMKEnforcedA.8.24
ElastiCache for Redis replication groups should be encrypted in transitEnforcedA.8.24
ElastiCache for Redis replication groups before version 6.0 should use Redis AuthEnforcedA.8.5 (supporting)
ELB application and classic load balancer logging should be enabledEnforcedA.8.15
ELB load balancers should prohibit public accessEnforcedA.8.3
FSx for OpenZFS file systems should be configured to copy tags to backups and volumesEnforcedA.5.13
FSx for Lustre file systems should be configured to copy tags to backupsEnforcedA.5.13
FSx for NetApp ONTAP file systems should be configured for Multi-AZ deploymentEnforcedA.8.14
FSx for OpenZFS file systems should be configured for Multi-AZ deploymentEnforcedA.8.14
FSx for Windows File Server file systems should be configured for Multi-AZ deploymentEnforcedA.8.14
API Gateway V2 stages should have access logging configuredEnforcedA.8.15
KMS CMK rotation should be enabledEnforcedA.8.5, A.8.24
Lambda functions CORS configuration should not allow all originsEnforcedA.8.3
Lambda functions should encrypt environment variables with a specified KMS keyEnforcedA.8.24 (supporting)
Lambda functions should be in a VPCEnforcedA.8.20, A.8.21, A.8.22
Lambda functions should restrict public URLEnforcedA.8.3
Log groups should have encryption at rest enabledEnforcedA.8.15, A.8.16, A.8.24
MSK clusters should require TLS for client-broker connectionsEnforcedA.8.12, A.8.24
Network Firewall firewalls should have subnet change protection enabledEnforcedA.8.32 (supporting)
OpenSearch domains should have audit logging enabledEnforcedA.8.15
OpenSearch domains should have at least three data nodesEnforcedA.8.14
OpenSearch domains should have encryption at rest enabledEnforcedA.8.24
OpenSearch domains internal user database should be disabledEnforcedA.8.2
OpenSearch domains should have logging to CloudWatch Logs enabledEnforcedA.8.15
OpenSearch domains node-to-node encryption should be enabledEnforcedA.8.12, A.8.24
RDS DB clusters should be configured to copy tags to snapshotsEnforcedA.5.13
RDS DB clusters should be encrypted at restEnforcedA.8.24
RDS DB clusters should be configured for multiple Availability ZonesEnforcedA.8.14
RDS DB instances should be integrated with CloudWatch logsEnforcedA.8.15
RDS DB instance encryption at rest should be enabledEnforcedA.8.24
RDS instances should be deployed in a VPCEnforcedA.8.20, A.8.21, A.8.22
RDS DB instances should have multiple AZ enabledEnforcedA.8.14
RDS DB instances should not use public subnetEnforcedA.8.3
RDS DB instances should prohibit public accessEnforcedA.8.3
Redshift clusters should have audit logging enabledEnforcedA.8.15
Redshift clusters should be encrypted with CMKEnforcedA.8.24
Redshift cluster encryption in transit should be enabledEnforcedA.8.12, A.8.24
Redshift clusters should have enhanced VPC routing enabledEnforcedA.8.20, A.8.21, A.8.22
Redshift clusters should have KMS encryption enabledEnforcedA.8.24
Redshift clusters should have Multi-AZ deployments enabledEnforcedA.8.14
Redshift clusters should prohibit public accessEnforcedA.8.3
S3 buckets should have cross-region replication enabledEnforcedA.8.14
S3 buckets should have default encryption enabledEnforcedA.8.24
S3 buckets should have lifecycle policies configuredEnforcedA.8.10
S3 buckets should have logging enabledEnforcedA.8.15
S3 buckets should not be accessible to all authenticated usersEnforcedA.8.3
S3 buckets should have policies that prohibit public accessEnforcedA.8.3
S3 buckets should prohibit public read accessEnforcedA.8.3
S3 buckets should prohibit public write accessEnforcedA.8.3
S3 buckets should have versioning enabledEnforcedA.8.10, A.8.13 (supporting)
S3 public access should be blocked at account levelEnforcedA.8.3
Step Functions state machines should have logging enabledEnforcedA.8.15
SNS topics should be encrypted at restEnforcedA.8.24
SQS queues should have encryption at rest enabledEnforcedA.8.24
EC2 VPC Block Public Access settings should block internet gateway trafficEnforcedA.8.3 (supporting)
VPC subnet auto assign public IP should be disabledEnforcedA.8.20, A.8.21, A.8.22
EC2 VPN connections should have logging enabledEnforcedA.8.15
ACM certificates should not use wildcard certificatesMappedA.8.24 (supporting)
API Gateway stages should have logging enabledMappedA.8.15
AppStream fleets should have default internet access disabledMappedA.8.3
Athena workgroups should be encrypted at restMappedA.8.24
Athena workgroups should have logging enabledMappedA.8.15
CloudFormation stacks should have rollback enabledMappedA.8.32 (supporting)
CloudTrail trails should be integrated with CloudWatch logsMappedA.8.15, A.8.16
CloudTrail trails should have logs encrypted using a customer managed KMS keyMappedA.8.15, A.8.16, A.8.24
CloudTrail trails should have log file validation enabledMappedA.8.15, A.8.16
CodeBuild projects should specify a KMS key for build output encryptionMappedA.8.24 (supporting)
CodeBuild projects should have logging enabledMappedA.8.4, A.8.15
CodeBuild projects should have S3 logs encryptedMappedA.8.15, A.8.24
CodeBuild report group exports should be encrypted at restMappedA.8.24
DynamoDB Accelerator (DAX) clusters should be encrypted at restMappedA.8.24
DynamoDB Accelerator clusters should be encrypted in transitMappedA.8.12, A.8.24
DMS endpoints for Redis OSS should have TLS enabledMappedA.8.24
DocumentDB clusters should have encryption at rest enabledMappedA.8.24
DocumentDB instance logging should be enabledMappedA.8.15
EBS snapshots should be encryptedMappedA.8.24
EC2 Client VPN endpoints should have client connection logging enabledMappedA.8.15
EC2 instances should not use multiple ENIsMappedA.8.20, A.8.21, A.8.22
EC2 instances should not use paravirtual instance typesMappedA.8.20, A.8.21, A.8.22
EC2 transit gateways should have auto accept shared attachments disabledMappedA.8.20, A.8.21, A.8.22
EKS clusters should be configured to have kubernetes secrets encrypted using KMSMappedA.8.5, A.8.24
ELB classic load balancers should span multiple availability zonesMappedA.8.14
Elasticsearch domains should have audit logging enabledMappedA.8.15
Elasticsearch domains should have at least three data nodesMappedA.8.14
Elasticsearch domains should be configured with at least three dedicated master nodesMappedA.8.14
ES domain encryption at rest should be enabledMappedA.8.24
Elasticsearch domain node-to-node encryption should be enabledMappedA.8.12, A.8.24
Glue data catalog metadata encryption should be enabledMappedA.8.15, A.8.24
Glue data catalog connection password encryption should be enabledMappedA.8.15, A.8.24
Glue jobs bookmarks encryption should be enabledMappedA.8.24
Glue jobs CloudWatch logs encryption should be enabledMappedA.8.15, A.8.24
Glue jobs S3 encryption should be enabledMappedA.8.24
IAM password policies should have minimum length set to 14 or greaterMappedA.5.15
IAM password policies should require at least one lowercase letterMappedA.5.15
IAM password policies should require at least one numberMappedA.5.15
IAM password policies should require at least one symbolMappedA.5.15
IAM password policies should require at least one uppercase letterMappedA.5.15
IAM password policies should prevent password reuseMappedA.5.15
IAM password policies should expire passwords within 90 days or lessMappedA.5.15
Kinesis firehose delivery streams should have server side encryption enabledMappedA.8.24
Kinesis streams should be encrypted with CMKMappedA.8.24
Kinesis streams should have server side encryption enabledMappedA.8.24
MQ brokers should have audit log streaming to CloudWatch enabledMappedA.8.15
MQ brokers should restrict public accessMappedA.8.3
MSK Connect connectors should be encrypted in transitMappedA.8.24
MSK connectors should have logging enabledMappedA.8.15
Neptune DB clusters should publish audit logs to CloudWatch LogsMappedA.8.15
Neptune DB clusters should be configured to copy tags to snapshotsMappedA.5.13
Neptune DB clusters should be encrypted at restMappedA.8.24
OpenSearch domains should be in a VPCMappedA.8.3
Redshift Serverless namespaces should export logs to CloudWatch LogsMappedA.8.15
Redshift Serverless workgroups should prohibit public accessMappedA.8.3
S3 buckets should have static website hosting disabledMappedA.8.3 (supporting)
SageMaker endpoint production variants should have an initial instance count greater than 1MappedA.8.14
SageMaker models should be in a VPCMappedA.8.20, A.8.21, A.8.22
SageMaker notebook instances should not have direct internet accessMappedA.8.3
SageMaker notebook instance encryption should be enabledMappedA.8.24
SageMaker notebook instances should be in a VPCMappedA.8.20, A.8.21, A.8.22
VPC endpoint services should have acceptance required enabledMappedA.8.21 (supporting)

Supporting: the control is partial or indirect evidence for the clause, not full enforcement.

Enforced or mapped without a named ISO 27001 clause

The catalog lists these 26 controls under ISO 27001 but names no ISO 27001 clause for them, so the register and the counts in D.3 leave them out. Each still links to its docs page.

ControlStatus
CloudFront distributions should require encryption in transitEnforced
EC2 launch templates should use Instance Metadata Service Version 2 (IMDSv2)Enforced
EFS file systems should be encrypted with CMKEnforced
Aurora PostgreSQL DB clusters should publish logs to CloudWatch LogsEnforced
RDS DB clusters should be encrypted with CMKEnforced
RDS DB instances should have logging enabledEnforced
RDS for MariaDB DB instances should publish logs to CloudWatch LogsEnforced
RDS for PostgreSQL DB instances should publish logs to CloudWatch LogsEnforced
RDS for SQL Server DB instances should publish logs to CloudWatch LogsEnforced
Redshift clusters should have audit logging and encryption enabledEnforced
S3 buckets should have default encryption enabled using KMSEnforced
S3 buckets with versioning enabled should have lifecycle policies configuredEnforced
SQS queues should be encrypted with KMS CMKEnforced
VPC security groups should restrict ingress from 0.0.0.0/0 or ::/0 to cassandra ports 7199 or 9160 or 8888Enforced
WAFv2 rules should have CloudWatch metrics enabledEnforced
API Gateway stages should have cache encryption at rest enabledMapped
CloudTrail trails should have at least one enabled trail present in a regionMapped
DataSync tasks should have logging enabledMapped
Elasticsearch domains should have internal user database enabledMapped
Elasticsearch domain should send logs to CloudWatchMapped
IAM password policies should have strong configurations with minimum length of 8 or greaterMapped
IAM password policies should have strong configurationsMapped
Redshift Serverless workgroups should have enhanced VPC routing enabledMapped
S3 buckets should have object logging enabledMapped
VPC security groups should not allow ingress from 0.0.0.0/0 to remote server administration ports (IPv4)Mapped
VPC security groups should not allow ingress from ::/0 to remote server administration portsMapped

Clause IDs for the auditor. Your stack stays as it is.

Compliance.tf works alongside your scanners, plan policy, CSPM and GRC tool. It sets the controls in the modules and lists the clause each one is there for.

D.5

Evidence

D.5.1

What compliance.tf gives your auditor

  • The ISO 27001 clause IDs behind each enforced setting, with stable control IDs and public docs pages.
  • The config snapshot bound to each environment, and the per-action audit log of promotions between environments.
D.5.2

What comes from your AWS account and GRC tool

Evidence of what actually runs comes from your own account, for example AWS Config and your CSPM. Your GRC tool keeps tracking policies and audit workflows.

D.6

Plans for ISO 27001

ISO 27001 is in the 30-day trial and in Full Access, $1,000 a year on AWS Marketplace. Schedule of fees.

D.7

Questions about ISO 27001

D.7.1

Is this ISO 27001:2013 or 2022?

Compliance.tf maps controls to ISO 27001:2022, the current version. The 2022 revision restructured Annex A from 114 controls in 14 domains to 93 controls in 4 themes (Organizational, People, Physical, Technological). Our modules focus on the Technological theme (A.8), which maps directly to AWS resource configuration.

D.7.2

Which Annex A controls does this cover?

Compliance.tf enforces controls from Annex A, for example cryptography (A.8.24), logging and monitoring (A.8.15 and A.8.16), access control (A.8.2 to A.8.5), network security (A.8.20 to A.8.22), and information deletion (A.8.10). These are the Annex A controls that translate directly to infrastructure configuration.

D.7.3

Can I adopt this gradually, or is it all-or-nothing?

Fully incremental. Start with one module in one environment. Your existing modules continue working untouched. If you use Terragrunt or Terramate to orchestrate your runs, nothing changes - you're only swapping the module source line. There is no global policy agent to deploy, no wrapper binary, no sidecar. Each module source line is independent.

D.7.4

What if we want to switch back?

Each module keeps the inputs and outputs of its terraform-aws-modules counterpart and needs no state migration, so switching back is the same source line change in reverse.