Search code examples
aws-cloudformationaws-secrets-manager

Using AWS Secrets manager's Secret in Cloudformation


I want to export the read_only_user's password to the EC2 instance. How can I access the created password inside the UserData?

Resources:
  ReadOnlyUserCredentials:
      Type: AWS::SecretsManager::Secret
      Properties:
        Name: !Sub "${AWS::StackName}/readonly-user-credentials"
        GenerateSecretString:
          SecretStringTemplate: '{"username": "read_only_user"}'
          GenerateStringKey: 'password'
          PasswordLength: 16
          ExcludeCharacters: '"@/\'
  WebServer:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-a4c7edb2
      InstanceType: t2.micro
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo "${!Join ['', ['{{resolve:secretsmanager:', !Ref ReadOnlyUserCredentials, ':SecretString:password}}' ]]}" > password

I tried using the !Join but of course that is not working. I will really appreciate any help here.

Update:

      UserData:
        Fn::Base64:
         Fn::Sub:
          - |
            echo ${PasswordStr} > password
          - PasswordStr: !Join ['', ['{{resolve:secretsmanager:', !Ref ReadOnlyUserCredentials, ':SecretString:password}}' ]]

By changing the code as shown above, I did get the resolve string, but it did not give me the actual password. How do I resolve the arn to get the plain password?


Solution

  • You probably do not want CFN to expand your secret in the user data because the password would be embedded in the base64 encoded user data script which is visible in the EC2 console.

    Instead you should take advantage of the fact that you have a script that executes on the host and call secrets manager at script execution time (warning, not tested):

    Resources:
      ReadOnlyUserCredentials:
          Type: AWS::SecretsManager::Secret
          Properties:
            Name: !Sub "${AWS::StackName}/readonly-user-credentials"
            GenerateSecretString:
              SecretStringTemplate: '{"username": "read_only_user"}'
              GenerateStringKey: 'password'
              PasswordLength: 16
              ExcludeCharacters: '"@/\'
      WebServer:
        Type: AWS::EC2::Instance
        Properties:
          ImageId: ami-a4c7edb2
          InstanceType: t2.micro
          UserData:
            Fn::Base64: !Sub |
              #!/bin/bash
              yum update -y
              yum install -y jq
              aws --region ${AWS::Region} secretsmanager get-secret-value --secret-id !Ref ReadOnlyUserCredentials --query SecretString --output text | jq -r .password > password