AWS Command
Structured guidance for AWS CloudFront, WAF, Lambda@Edge, and multi-account security patterns.
Interactive Wizard (fires when no mode is provided)
When invoked with no arguments, ask before proceeding:
Q1 — Mode?
What do you need?
1. cloudfront — distributions, OAC, cache policies, security headers, Lambda@Edge
2. waf — web ACLs, managed rule groups, rate limiting, false positive tuning
3. lambda-edge — CloudFront Functions vs Lambda@Edge, viewer/origin events
4. multi-account — Firewall Manager, cross-account OAC, FMS WAF enforcement
5. orgs — Organizations, SCPs, OU design, account vending, Control Tower
6. review — production-readiness review of CloudFront + WAF config
7. terraform — generate a Terraform module scaffold
Enter 1–7 or mode name:
Q2 — Context (after mode selected):
- cloudfront:
Describe the issue or what you want to build (distribution, OAC, cache, edge function): - waf:
Describe the use case — new WebACL, false positive, adding a rule, or multi-account enforcement: - lambda-edge:
What does the edge function need to do? (auth, URL rewrite, A/B test, dynamic routing): - multi-account:
How many accounts? Do you have FMS administrator configured in the security account? - orgs:
Describe what you need — SCP enforcement, OU design, account vending, or Control Tower setup: - review / terraform: no follow-up needed — proceed directly
Activation
Invoke with /platform-skills:aws followed by a mode, or describe your problem and the command will route automatically.
/platform-skills:aws cloudfront # CloudFront distributions, OAC, cache, security headers
/platform-skills:aws waf # WAF web ACLs, managed rules, rate limiting
/platform-skills:aws lambda-edge # Lambda@Edge and CloudFront Functions
/platform-skills:aws multi-account # Firewall Manager, cross-account, Organizations
/platform-skills:aws review # Production-readiness review of your config
/platform-skills:aws terraform # Generate Terraform module scaffold
Mode: cloudfront
Triggers: distribution, CDN, OAC, cache behavior, price class, CNAME, SSL, geo restriction, origin, CloudFront
Reference: references/aws-cloudfront.md
Steps:
-
Identify the problem layer:
- Origin access — OAC/OAI, S3 bucket policy, cross-account origin
- Cache — TTL, cache key, cache policy vs origin request policy
- Security — response headers, HTTPS enforcement, WAF attachment
- Edge compute — Lambda@Edge vs CloudFront Functions decision
- Logging — standard logs, real-time logs, Athena
-
Check for the common footguns:
- WAF for CloudFront must be
CLOUDFRONTscope inus-east-1 - OAC not OAI — OAI is legacy; new distributions must use OAC
- Lambda@Edge must use numbered version ARN (
qualified_arn), not$LATEST - ACM certificate for custom domains must be in
us-east-1
- WAF for CloudFront must be
-
Provide: problem diagnosis, Terraform snippet, validation steps, rollback plan.
Key Terraform resources:
| Resource | Purpose |
|---|---|
aws_cloudfront_distribution | The distribution |
aws_cloudfront_origin_access_control | OAC (replaces OAI) |
aws_cloudfront_cache_policy | Custom cache key and TTL |
aws_cloudfront_origin_request_policy | What to forward to origin |
aws_cloudfront_response_headers_policy | Security headers |
aws_cloudfront_function | CloudFront Function (JS, viewer events) |
aws_cloudfront_realtime_log_config | Real-time logs to Kinesis |
Mode: waf
Triggers: WAF, web ACL, rule group, managed rules, rate limit, Bot Control, CAPTCHA, Challenge, IP set, geo block
Reference: references/aws-waf.md
Steps:
-
Confirm scope:
CLOUDFRONT→ must useus-east-1provider aliasREGIONAL→ same region as the protected resource
-
Classify the request:
- New WebACL → baseline rule groups + rate limit + logging
- False positive → use
rule_action_overrideto Count the specific rule - Adding rule → Count first, monitor 24–48h, then Block
- Performance → review sampled requests, check which rules add latency
- Multi-account → use Firewall Manager (see multi-account mode)
-
Provide: exact rule block, priority placement, visibility config, logging config.
Baseline rule groups (always include for CloudFront):
# Priority 5 — IP reputation (free)
AWSManagedRulesAmazonIpReputationList
# Priority 10 — Core Rule Set (free)
AWSManagedRulesCommonRuleSet
# Priority 15 — Known bad inputs: Log4Shell, SSRF (free)
AWSManagedRulesKnownBadInputsRuleGroup
# Priority 30 — Rate limit: 2000 req/5min per IP
rate_based_statement { limit = 2000; aggregate_key_type = "IP" }
Paid additions (evaluate based on risk):
AWSManagedRulesBotControlRuleSet— bot traffic (Common or Targeted level)AWSManagedRulesATPRuleSet— credential stuffing on login endpointsAWSManagedRulesACFPRuleSet— account creation fraud on registration endpoints
Mode: lambda-edge
Triggers: Lambda@Edge, CloudFront Functions, viewer-request, origin-request, edge function, A/B test, auth at edge, URL rewrite
Reference: references/aws-cloudfront.md → Lambda@Edge section
Decision — CloudFront Functions vs Lambda@Edge:
Need network calls? → Lambda@Edge (CloudFront Functions have no network access)
Need body access? → Lambda@Edge (origin events only)
Need execution > 1ms? → Lambda@Edge
Need viewer-request/response only? → CloudFront Functions (6× cheaper)
Need complex logic / Node modules? → Lambda@Edge
Need dynamic config without deploy?→ CloudFront Functions + KeyValueStore
Simple URL rewrite / header add? → CloudFront Functions
Auth token validation (JWT)? → Lambda@Edge viewer-request
Dynamic origin routing? → Lambda@Edge origin-request
Lambda@Edge checklist:
- Function authored in
us-east-1 -
publish = truein Terraform - Using
qualified_arn(notarn) inlambda_function_association - IAM trust includes
edgelambda.amazonaws.comANDlambda.amazonaws.com - No VPC attachment
- No environment variables (use KeyValueStore for config)
- No
$LATESTversion reference - Log group pre-created in
us-east-1
Mode: multi-account
Triggers: Firewall Manager, FMS, Organizations, cross-account, OU, security account, delegated admin, centralized WAF
References: references/aws-waf.md → Multi-account section, references/aws-cloudfront.md → Multi-account patterns
Steps:
-
Confirm prerequisites:
- AWS Organizations with all features enabled
- FMS administrator account designated
- Member accounts in-scope (OU or account list)
-
Choose pattern:
| Pattern | When to use |
|---|---|
| Shared CloudFront account | Platform team owns distributions; app teams own origins |
| Per-account distributions + FMS WAF | App team autonomy; security team enforces WAF centrally |
| FMS audit mode first | Existing org — identify violations before enforcing |
-
FMS WAF policy structure:
preProcessRuleGroups(priority 0–19) — security team, locked- App team rules (priority 20–79) — local additions allowed
postProcessRuleGroups(priority 80+) — security team, locked
-
Cross-account OAC pattern (shared CDN account):
- Bucket policy
AWS:SourceArnscoped to distribution ARN works cross-account - Distribution ARN includes the CDN account ID — spoke accounts are locked to that distribution
- Bucket policy
-
Provide: FMS policy Terraform, OAC cross-account bucket policy, SCP to enforce WAF attachment.
Mode: orgs
Triggers: Organizations, SCPs, OU, account vending, Control Tower, delegated admin, account factory, guardrails
Steps:
-
Identify the request:
- SCP design — what to restrict and at which OU level
- OU structure — hierarchy that reflects environment and risk boundary
- Account vending — automated account creation with baseline config
- Control Tower — managed landing zone setup and customizations
-
OU design principles:
OU Accounts SCP stance Security Log archive, Audit Deny all except security tooling Infrastructure Network, Shared services Restricted; platform team only Workloads/Prod Production app accounts Deny risky actions (delete trail, disable GuardDuty) Workloads/SDLC Dev, staging accounts More permissive; deny prod data access Sandbox Developer personal accounts Deny spend > threshold; deny production-touching actions -
Essential SCPs (apply at root or Workloads OU):
{"Version": "2012-10-17","Statement": [{"Sid": "DenyLeavingOrg","Effect": "Deny","Action": "organizations:LeaveOrganization","Resource": "*"},{"Sid": "DenyDisableCloudTrail","Effect": "Deny","Action": ["cloudtrail:StopLogging", "cloudtrail:DeleteTrail"],"Resource": "*"},{"Sid": "DenyDisableGuardDuty","Effect": "Deny","Action": ["guardduty:DeleteDetector", "guardduty:DisassociateFromMasterAccount"],"Resource": "*"},{"Sid": "DenyRootUser","Effect": "Deny","Action": "*","Resource": "*","Condition": {"StringLike": { "aws:PrincipalArn": "arn:aws:iam::*:root" }}}]} -
Account vending (Account Factory for Terraform — AFT):
module "account_request" {source = "github.com/aws-ia/terraform-aws-control_tower_account_factory"control_tower_parameters = {AccountEmail = "platform+prod-payments@company.com"AccountName = "prod-payments"ManagedOrganizationalUnit = "Workloads/Prod"SSOUserEmail = "admin@company.com"}account_tags = { env = "prod", team = "payments", cost-center = "eng" }account_customizations_name = "prod-baseline"} -
Delegated administrators — always delegate to a dedicated account, never the management account:
- GuardDuty:
aws organizations register-delegated-administrator --service-principal guardduty.amazonaws.com - SecurityHub:
--service-principal securityhub.amazonaws.com - FMS: designated separately via FMS console or Terraform
- GuardDuty:
-
Validate SCP effect before attaching:
# Simulate an action under the SCP (requires aws-cli v2)aws iam simulate-custom-policy \--policy-input-list file://scp.json \--action-names cloudtrail:StopLogging \--resource-arns "*"
→ Next: Run /platform-skills:aws review to audit the account configuration, or /platform-skills:compliance checklist to validate SOC 2 controls across the org.
Mode: review
Triggers: review, production ready, production checklist, audit my CloudFront, audit my WAF
Structured production-readiness review. Ask for:
- The CloudFront distribution config (Terraform or describe key settings)
- The associated WAF WebACL config
- The origin type (S3, ALB, custom)
Then evaluate against:
CloudFront:
- Viewer protocol:
https-onlyorredirect-to-https - Minimum TLS:
TLSv1.2_2021 - OAC configured (not OAI, not public bucket)
- WAF attached
- Response headers policy: HSTS, X-Frame-Options, X-Content-Type-Options
- Standard logging enabled
- Price class appropriate for audience geography
- Lambda@Edge:
qualified_arnused,publish = true
WAF:
- Scope is
CLOUDFRONT, provider isus_east_1 - IP reputation list included
- Core Rule Set included
- Rate limiting on sensitive endpoints
- Logging enabled, sensitive headers redacted
- CloudWatch metrics enabled per rule
- New rules tested in Count mode before Block
Multi-account:
- FMS policy in place (if on Organizations with >3 accounts)
- Compliance dashboard reviewed
- Centralized logging configured
Report: CRITICAL issues (must fix before launch) → WARNINGS (should fix) → INFORMATIONAL.
Mode: terraform
Triggers: generate terraform, scaffold, create module, write terraform for
Generate a Terraform module scaffold using best practices. Ask:
- What are you building? (CloudFront + S3, CloudFront + ALB, WAF only, FMS policy)
- Multi-account? (yes/no — affects provider aliases and FMS resources)
- Lambda@Edge or CloudFront Functions needed? (affects us-east-1 provider alias)
- Existing WAF or new? (affects whether WAF module is separate)
Then generate complete module files:
<module-name>/
├── versions.tf # terraform{} block + required_providers + provider aliases
├── variables.tf # typed inputs with validation{} blocks
├── locals.tf # computed values, name prefixes
├── main.tf # all resources
└── outputs.tf # ARNs, IDs, domain names with descriptions
Non-negotiable patterns in every generated module:
Common mistakes
- WAF scope in wrong region —
CLOUDFRONTscope WebACLs must be created inus-east-1. Any other region returnsWAFInvalidParameterException. Use a provider aliasaws.us_east_1explicitly - OAI instead of OAC — OAI (Origin Access Identity) is legacy. New distributions must use OAC (
aws_cloudfront_origin_access_control). OAI does not support non-S3 origins or newer signing protocols - Lambda@Edge using
$LATEST—$LATESTis not a publishable version and cannot be associated with CloudFront. Setpublish = truein the resource and referenceaws_lambda_function.this.qualified_arn - ACM certificate not in us-east-1 — CloudFront only accepts ACM certificates created in
us-east-1, regardless of where the distribution serves traffic - SCP accidentally blocking the management account — SCPs do not apply to the management account. Policies intended to restrict member accounts work correctly; don't expect them to constrain root
- Attaching WAF rules directly in Block mode — always Count first for 24–48h before switching to Block. A misconfigured rule in Block mode silently drops legitimate traffic
# versions.tf — always pin providers
terraform {
required_version = ">= 1.7.0"
required_providers {
aws = { source = "hashicorp/aws"; version = ">= 5.0.0" }
}
}
# variables.tf — always include description and type
variable "name" {
type = string
description = "Name prefix applied to all resources."
validation {
condition = length(var.name) <= 32
error_message = "Name must be 32 characters or fewer."
}
}
variable "default_tags" {
type = map(string)
description = "Tags applied to all resources via provider default_tags."
default = {}
}
# Provider — always use default_tags
provider "aws" {
region = var.aws_region
default_tags { tags = var.default_tags }
}
# CloudFront WAF / Lambda@Edge — always add us-east-1 alias
provider "aws" {
alias = "us_east_1"
region = "us-east-1"
default_tags { tags = var.default_tags }
}
# outputs.tf — always include description
output "distribution_arn" {
description = "ARN of the CloudFront distribution."
value = aws_cloudfront_distribution.this.arn
}