Alexandre Santos
Alexandre Santos

Reputation: 8338

Reading a secret using CloudFormation

I am trying to create an AWS stack in CloudFormation having a secret in the JSON.

I don't want the value of the secret displayed in the parameters and I don't want my instance (fargate or ec2) to access the secrets manager. I want CloudFormation to retrieve the value from the secrets manager and inject it in the template during runtime.

This is what I did:

  1. Create a secret

  2. Create a template using Designer

  3. Read the secret and create a resource. In this case I am creating a bucket that has as a tag the secret. I know this is not secure, but the bucket is being used just as a proof of concept.

  4. Validate that the bucket contains a tag with the secret

This is my template:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "create a single S3 bucket",
    "Resources": {
        "SampleBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": "asantostestbucket",
                "Tags" : [
                    {
                        "Key" : "keyname",
                        "Value" : "{{resolve:secretsmanager:dev/learning:SecretString:hello}}"
                    }
            ]
            }
        }
    }
}

Which is giving me the error One or more tags are not valid.

How can I indicate to CloudFormation that I want it to read the secret, instead of trying to read the tag as text? In other words, replace "{{resolve:secretsmanager:dev/learning:SecretString:hello}}" with the value, instead of reading it as a text.

Upvotes: 6

Views: 13948

Answers (2)

Yogesh
Yogesh

Reputation: 1

If you already have a secret in the secrets manager(for eg. API key) and your lambda function can read the secret. Just add the lines 4 and 5, which is to describe and get secret to your cloudformation YAML template.

Action:
  - 'logs:CreateLogGroup'
  - 'logs:CreateLogStream'
  - 'logs:PutLogEvents'
  - 'secretsmanager:DescribeSecret'
  - 'secretsmanager:GetSecretValue'
Resource: '*'`

Upvotes: 0

John Rotenstein
John Rotenstein

Reputation: 269101

To reproduce this situation, I did the following:

  • In the Secrets Manager, created a new secret
    • "Other type of secrets"
    • Key: hello
    • Value: surprise
    • Secret name: dev/learning
  • Tested the secret using the AWS CLI

Here's the output:

aws secretsmanager get-secret-value --secret-id dev/learning
{
    "ARN": "arn:aws:secretsmanager:ap-southeast-2:123456789012:secret:dev/learning-kCxSK3",
    "Name": "dev/learning",
    "VersionId": "...",
    "SecretString": "{\"hello\":\"surprise\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": 1560925072.106
}
  • Launched the CloudFormation template you supplied above (but with a different bucket name)

Result: I received the message One or more tags are not valid

So, I got the same result as you did.

I then tried creating a different type of resource using the secret:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "SecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "{{resolve:secretsmanager:dev/learning:SecretString:hello}}"
            }
        }
    }
}

This worked successfully:

aws ec2 describe-security-groups --group-id sg-03cfd71f4539a4b7e
{
    "SecurityGroups": [
        {
            "Description": "surprise",
            ...

So, it seems that the {{resolve}} is behaving correctly, but for some reason the S3 Tag doesn't like it.

Bottom line: It is possible, but not advisable.

Upvotes: 7

Related Questions