A company uses AWS CloudFormation to deploy infrastructure. The security team wants to ensure that no sensitive data, such as database passwords, is exposed in plaintext in the CloudFormation templates. What is the MOST secure way to handle secrets?
Using CloudFormation dynamic references to AWS Systems Manager Parameter Store or AWS Secrets Manager lets the service fetch the secret value at stack create/update time, so the actual secret never appears in the template, AWS CloudFormation API calls, or stack logs. With a parameter reference like 'ssm-secure:MyParameter' or a secretsmanager reference, CloudFormation passes the resolved value directly to the resource while the template retains only the reference. This aligns with least-privilege access and supports rotation, because you can attach a version to the reference and rotate the backing secret without editing the template.
Why this answer
AWS Systems Manager Parameter Store and AWS Secrets Manager support dynamic references in CloudFormation templates, allowing you to reference secret values without exposing them in plaintext. CloudFormation resolves these references at deployment time, retrieving the actual secret value from the secure store, and never stores the secret in the template or stack metadata. This approach ensures secrets are managed, rotated, and audited centrally, adhering to security best practices.
Exam trap
The trap here is that candidates may think encrypting the secret with KMS (Option A) or storing it in an encrypted S3 bucket (Option C) is sufficient, but they overlook that the encrypted data or reference URL is still exposed in the template, and the decryption key or bucket access must be managed separately, which is less secure than using a dedicated secrets service with dynamic references.
How to eliminate wrong answers
Option A is wrong because including ciphertext in the template still exposes the encrypted secret in the template itself, and you would need to manage the KMS key and decryption logic separately, which is less secure and more complex than using a native secrets service. Option C is wrong because storing secrets in an encrypted S3 bucket and including the S3 URL in the template still exposes the URL (and potentially the bucket name) in plaintext, and the template would need IAM permissions to access the bucket, increasing the attack surface. Option D is wrong because passing secrets as plaintext parameters at launch time means the secret value is visible in the CloudFormation console, API logs (AWS CloudTrail), and any automation scripts, violating the requirement to avoid plaintext exposure.