COST
Log groups without retention keep growing and quietly turn debugging data into a recurring bill.
How we detect it
List log groups with no retention policy or retention that is longer than the account actually needs.
Resolved by
retention: logs.RetentionDays.ONE_MONTHOur CDK building block
Our LogGroup building block sets one-month retention by default and supports KMS encryption for sensitive logs.
For manually deployed accounts
Set retention on existing log groups, then move future log groups into IaC so the setting does not drift.
Read the detailed guide →SECURITY
Weak S3 bucket baseline
Storage buckets often miss one or more basics: public access blocking, SSL enforcement, encryption, versioning, lifecycle, or access logs.
How we detect it
Review public access settings, bucket policy, ACLs, encryption, versioning, lifecycle rules, and server access logging.
Resolved by
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALLOur CDK building block
Our Bucket building block defaults to KMS encryption, versioning, block public access, SSL enforcement, access logging, and lifecycle rules.
For manually deployed accounts
Enable block public access, review policies and ACLs, add encryption and lifecycle rules, then codify the bucket baseline.
COST
Unattached EBS volumes
Volumes can survive instance deletion and keep billing even when nobody knows what they belong to.
How we detect it
Find EBS volumes in available state and check whether they have owner, environment, and application tags.
Resolved by
removalPolicy + owner/env/appId tagsOur CDK building block
Our Disk building block creates encrypted gp3 volumes with standard tags and an explicit removal policy.
For manually deployed accounts
Confirm ownership, snapshot if needed, delete unused volumes, tag retained volumes, and use IaC for new disks.
COST
Missing ownership and cost tags
Without tags, teams cannot tell who owns spend, risk, cleanup, or remediation work.
How we detect it
Check critical resources for appId, costCenter, owner, env, and createdBy tags.
Resolved by
Tags.of(resource).add("owner", owner)Our CDK building block
Our CDK building blocks expose standard tag props so ownership and cost metadata are applied consistently.
For manually deployed accounts
Apply tags to existing resources, agree the required tag policy, and enforce the same tags in all new deployments.
ARCHITECTURE
Production changes without approval gates
A fragile deployment path lets high-risk infrastructure changes reach production without the right review.
How we detect it
Review pipelines, environment separation, branch rules, and whether sensitive stacks require manual approval.
Resolved by
stackApprovals: [{ stack, comment }]Our CDK building block
Our DomainPipeline building block supports domain stages, parallel deployment waves, and per-stack approval gates.
For manually deployed accounts
Document the current release path, add approval gates around production changes, then migrate repeatable deploys into a managed pipeline.
ARCHITECTURE
Backups without restore confidence
A backup setting is not a recovery plan unless the team has proven restore works inside the expected time window.
How we detect it
Review backup schedules, snapshot age, restore-test evidence, RPO/RTO targets, and ownership.
Resolved by
defined retention + restore test cadenceOur CDK building block
This is currently an audit recommendation and future building-block candidate: codify retention, ownership, and restore testing where possible.
For manually deployed accounts
Verify existing backups, run a restore test, document RPO/RTO and owner, then codify backup settings where possible.