This policy recommends enabling automatic key rotation on AWS Key Management Service (AWS KMS) customer managed keys. Rotation generates new cryptographic material for a key on a recurring schedule, limiting how long any single piece of key material stays in use and reducing the impact if it were ever exposed. Use this policy on any symmetric encryption customer managed key that protects long-lived data, especially keys tied to compliance frameworks that require periodic key rotation.
Attribute | Detail |
|---|---|
Cloud Provider | Amazon Web Services (AWS) |
Resource Type | KMS customer managed keys (symmetric encryption) |
Terraform Attribute |
|
Compliant Value |
|
Cost Impact | Adds up to $2/month per key, capped after the second rotation, on top of the $1/month base key fee |
Why This Policy Matters
How It Helps Reduce Cloud Costs
Automatic key rotation is a security control more than a cost control, but it is one of the cheapest security controls available in AWS KMS. Enabling it on a customer managed key adds no charge for the base rotation mechanism itself. AWS only bills an additional $1/month for the first rotation and $1/month for the second, and every rotation after that is free. Compared to the cost of investigating and remediating a real key compromise, or the cost of a failed compliance audit that blocks a deal or certification renewal, this is a negligible expense.
This policy corresponds to AWS Security Hub control KMS.4, which checks whether AWS KMS key rotation is enabled. Teams that already run AWS Security Hub or a similar compliance tool are likely tracking this at the account level. Catching it in Terraform before a key ships closes the gap earlier, at the pull request stage, rather than as a finding discovered days or weeks later in a security dashboard.
Potential Savings
There is no direct cloud bill reduction from this policy in the way that instance right-sizing or storage tier changes produce one. The value here is risk avoidance: keys without rotation stay on the same cryptographic material indefinitely, and a compromised key stays exploitable for as long as it remains active. Teams that enable rotation by default on every new aws_kms_key resource avoid the larger, harder-to-quantify cost of a delayed incident response or a failed audit finding that has to be remediated retroactively across every environment.
Key rotation is a compliance checkbox for some teams and a genuine security control for others, but either way it costs almost nothing to enable, and there is little reason not to turn it on for every eligible key.
Implementation Guide
Infrastructure-as-Code Example (Terraform)
The following examples show a KMS key created without rotation enabled, and the corrected configuration that turns it on.
Non-compliant configuration: rotation not enabled
enable_key_rotation defaults to false when it is omitted, so this key never rotates its cryptographic material unless someone remembers to turn rotation on manually later. This is a common source of unnoticed security debt, since the key still works correctly for encryption and decryption either way.
Compliant configuration: automatic rotation enabled
Adding enable_key_rotation = true is a one-line change, but it is exactly the kind of one-line change that gets missed when a Terraform module ships without an opinionated default. The optional rotation_period_in_days attribute lets a team set a custom cadence between 90 and 2560 days; omitting it keeps the default 365-day schedule.
Step-by-Step Fix Instructions
List every
aws_kms_keyresource in Terraform state and check whetherenable_key_rotationis set totrue.For each key without rotation enabled, confirm it is a symmetric encryption key with AWS-generated key material. Automatic rotation is not available for asymmetric keys, HMAC keys, keys with imported key material, or AWS managed keys.
Add
enable_key_rotation = trueto the resource block. Setrotation_period_in_daysif the team needs a cadence other than the 365-day default.Run
terraform planto confirm the change only modifies the rotation setting and does not replace the key.Apply the change and confirm with the AWS CLI that rotation is active.
Add Infracost to CI/CD so any future
aws_kms_keyresource created withoutenable_key_rotationgets flagged in the pull request before it merges.
Best Practices
Set
enable_key_rotation = trueas the default in shared Terraform modules that create KMS keys, so rotation is on from the start rather than something a team has to remember to add later.Use
rotation_period_in_daysto align the rotation cadence with internal compliance requirements, such as a 90-day period for keys in a PCI-scoped environment, instead of accepting the 365-day default everywhere.This policy does not apply to AWS managed keys (aliases like
aws/s3oraws/rds), which already rotate automatically every year and cannot be configured throughaws_kms_key.Review rotation status on a recurring basis rather than treating a one-time Terraform change as sufficient, since rotation settings can also be changed outside Terraform through the console or CLI.
Tools and Scripts
Infracost supports this policy check in its free trial and paid plans. When Infracost runs in CI/CD, it evaluates aws_kms_keyresources introduced or modified in a pull request and flags any key missing enable_key_rotation in the PR comment before the code merges.
Infracost's AutoFix feature can open a pull request with enable_key_rotation = true already added to the flagged resource. A human still needs to review and merge that change, since AutoFix drafts the fix rather than applying it directly.
To check current rotation status across existing keys using the AWS CLI:
Examples of Impact
Illustrative example: rotation missed at creation. A platform team adds a new aws_kms_key resource for an application data store and ships it without enable_key_rotation. Six months later, a compliance audit flags the key against AWS Security Hub control KMS.4, and the team has to track down every environment where the same module was reused to apply the same one-line fix retroactively.
Illustrative example: caught before merge. A pull request adds a new aws_kms_key for a data pipeline without enable_key_rotation. Infracost flags the missing attribute in the PR comment, the reviewer requests the change, and the fix ships in the same pull request instead of surfacing as a finding in next quarter's security review.
(These are illustrative, composite scenarios, not specific customer accounts.)
Considerations and Caveats
Only symmetric encryption keys qualify: automatic rotation is supported only for symmetric encryption KMS keys with AWS-generated key material. Asymmetric keys, HMAC keys, and keys with imported key material need manual rotation instead.
AWS managed keys already rotate: keys with an alias like
aws/s3rotate automatically every year and cannot be configured through theaws_kms_keyresource.Rotation does not re-encrypt existing data: only new encryption operations use the newest key material. Data encrypted under an earlier key version continues to decrypt correctly using the retained prior key material.
Modest added cost: enabling rotation adds up to $2/month per key, capped after the second rotation, on top of the $1/month base fee for a customer managed key.
Custom rotation periods have limits:
rotation_period_in_daysaccepts values between 90 and 2560 days. Values outside that range are rejected.
Related Policies and Concepts
Security-hardening policies like this one tend to cluster by discipline rather than by cloud provider, so the related items below span more than one product group.
EC2 - require Instance Metadata Service Version 2 (IMDSv2): another Compute-group FinOps policy that enforces a security-hardening default directly in Terraform rather than relying on manual configuration review.
App Service - consider using latest TLS version: a related Compute-group policy that applies the same secure-by-default discipline to a different resource type.
Storage Account - consider disabling public network access: an Object Storage-group policy that pairs with this one when auditing a broader set of security-hardening checks across cloud providers.
"How to Enforce Cloud Cost Policies in Your CI/CD Pipeline": a planned Infracost resource article covering the broader workflow of catching policy violations, cost and security alike, at the pull request stage.
Frequently Asked Questions (FAQs)
Is this policy supported in Infracost?
Yes. Infracost evaluates aws_kms_key resources in pull requests and flags any key without enable_key_rotation set to true, so a team can add rotation before the resource merges. This check is available in the free trial and all paid plans.
Can this policy be customized?
Yes. Teams can adjust the policy's scope in Infracost, for example limiting the check to specific KMS keys or Terraform modules, rather than applying the default configuration everywhere.
Does Infracost automatically fix violations?
Not on its own. Infracost's AutoFix feature can open a pull request with enable_key_rotation = true already added to the flagged aws_kms_key resource, but a human still needs to review and merge that change.
Is this policy cloud-agnostic?
No. This specific policy targets AWS KMS and the aws_kms_key resource in the aws Terraform provider. Other cloud providers have their own key rotation settings, but the resource and attribute names differ.
How often should I review KMS key rotation status?
Teams running Infracost in CI/CD get a check on every pull request that touches an aws_kms_key resource. For keys already in place, review rotation status on a recurring basis using the AWS CLI; a quarterly audit is a reasonable cadence for most teams.
Does enabling automatic key rotation cause any downtime?
No. Enabling enable_key_rotation on an AWS KMS key does not interrupt encryption or decryption operations. The key ID, ARN, and key policies stay the same, and applications referencing the key continue to work without any changes.
What is the default rotation period for an AWS KMS key?
The default rotation period is 365 days. Teams can set a custom cadence with rotation_period_in_days, valid between 90 and 2560 days, instead of accepting the default.
Create Free Account
This policy is supported in Infracost and available in the free trial. Sign up today and scan your code using our entire library of FinOps policies.