how to create a dynamic secret key/pair and pass it to the user data whose name is also dynamic in Cloudformation

0

i have two problems:

  • i have the following how do i create a secretString by passing environment variable
Resources:
  MHCSecret:
    Type: 'AWS::SecretsManager::Secret'
    Properties:
      Name: !Sub MHSecret-{BuildEnvironment}
      Description: This secret has a hardcoded password in SecretString (use GenerateSecretString instead)
->>>      SecretString: '{"run_env":"{BuildEnvironment}","enc_key":3?kdfjs","eureka_password":"devadmin"}'
  • how do i use the above secret into the user data ->
  MHCLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub MRxAssist-${AWSEnvironment}
      LaunchTemplateData:
        IamInstanceProfile:
          Arn: !Ref IAMInstanceProfile
        DisableApiTermination: true
        ImageId: !Ref AmiId
        InstanceType: !Ref InstanceType
        KeyName: !Ref SSHKey
        SecurityGroupIds:
          - !Ref InstanceSGFullAccess
          - !Ref InstanceSGOutBoundAccess
          - !ImportValue
              'Fn::Sub': '${AWSEnvironment}-OracleAccessSecurityGroup' 
        UserData:
          Fn::Base64: >
            #!/bin/bash
            timedatectl set-timezone America/New_York
            yum -y update
            yum install -y jq

->>            run_env=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHCSecret{BuildEnvironment????} --query SecretString --output text | jq .run_env)
            enc_key=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHCSecret --query SecretString --output text | jq .enc_key)
            eureka_password=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHCSecret --query SecretString --output text | jq .eureka_password)

2 Answers
0

i have the following how do i create a secretString by passing environment variable

I thought we could use the Sub function here.
For example, the following template would be a good idea.

Resources:
  MHCSecret:
    Type: 'AWS::SecretsManager::Secret'
    Properties:
      Name: !Sub MHSecret-${BuildEnvironment}
      Description: This secret has a hardcoded password in SecretString (use GenerateSecretString instead)
      SecretString: 
        !Sub |-
          {
            "run_env": "${BuildEnvironment}",
            "enc_key": "3?kdfjs",
            "eureka_password": "devadmin"
          }

how do i use the above secret into the user data ->

This one should be as follows.
Basically, I tried to use "!Sub" to get the variables.

  MHCLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: !Sub MRxAssist-${AWSEnvironment}
      LaunchTemplateData:
        IamInstanceProfile:
          Arn: !Ref IAMInstanceProfile
        DisableApiTermination: true
        ImageId: !Ref AmiId
        InstanceType: !Ref InstanceType
        KeyName: !Ref SSHKey
        SecurityGroupIds:
          - !Ref InstanceSGFullAccess
          - !Ref InstanceSGOutBoundAccess
          - !ImportValue
              'Fn::Sub': '${AWSEnvironment}-OracleAccessSecurityGroup' 
        UserData:
          Fn::Base64: 
            !Sub |-
              #!/bin/bash
              timedatectl set-timezone America/New_York
              yum -y update
              yum install -y jq

              run_env=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHSecret-${BuildEnvironment} --query SecretString --output text | jq .run_env)
              enc_key=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHSecret-${BuildEnvironment} --query SecretString --output text | jq .enc_key)
              eureka_password=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHSecret-${BuildEnvironment} --query SecretString --output text | jq .eureka_password)
profile picture
EXPERT
answered a year ago
  • so i also have this in the User Data ->

    case $EC2_AVAIL_ZONE in us-east-1b) echo "127.0.0.1 assist-test-us-east-1b-76b6e2daf8dff55d.elb.us-east-1.amazonaws.com" >> /etc/hosts ;; us-east-1c) echo "127.0.0.1 assist-test-us-east-1c-fef13d151a1db177.elb.us-east-1.amazonaws.com" >> /etc/hosts ;; esac

    would you know how to pass

    !GetAtt 'ELBCloud1C.DNSName' where ELBCloud1C is the logicalID of the ELB in 1c.

    i suppose ELB won't exist when the ec2 is created and user data is added

  • Sorry, the above alone will cause an error, so I would suggest the following.

            UserData:
              Fn::Base64: 
                !Sub 
                - |-
                  #!/bin/bash
                  timedatectl set-timezone America/New_York
                  yum -y update
                  yum install -y jq
        
                  export LOAD_BALANCER_DNS=${LoadBalancerDNS}
                  run_env=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHSecret-${BuildEnvironment} --query SecretString --output text | jq .run_env)
                  enc_key=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHSecret-${BuildEnvironment} --query SecretString --output text | jq .enc_key)
                  eureka_password=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHSecret-${BuildEnvironment} --query SecretString --output text | jq .eureka_password)
                  echo "127.0.0.1  ${LOAD_BALANCER_DNS}" >> /etc/hosts
                - LoadBalancerDNS: !GetAtt 'ELBCloud1C.DNSName'
                  
    

    You also need to use DependsOn to create an EC2 after the ELB. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html

0

Hi, there is another way: you can access the value of any !Ref or !GetAtt and include it in your user data via !Sub that will substitute the Refs and GetAtts with their value.

For example

AppDef:
    Type: AWS::SSM::Parameter
    DeletionPolicy: Delete
    Properties:
      Type: 'String'
      Value: !Sub | 
        {
          "template-version": "2.0",
          "source-locations": [
            {
              "source-id": "s3-source",
              "source-type": "s3",
              "properties": {
                "s3-bucket": "${BucketName}",
                "s3-key-prefix": "${AppKey}"
              }
            }
          ],

${BucketName} and ${AppKey} will be substituted with their values produced elsewhere in the yaml

profile pictureAWS
EXPERT
answered a year ago
profile picture
EXPERT
reviewed a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions