Template error: variable names in Fn::Sub syntax must contain only alphanumeric characters, underscores, periods, and colons when using !Sub with bash

0

hi think someone here helped me resolve the issue, on substituting the 'BuildEnvironment'. here -> https://repost.aws/ja/questions/QUMP7MdW-FQuW8sD6g8BhQ8Q/how-to-create-a-dynamic-secret-key-pair-and-pass-it-to-the-user-data-whose-name-is-also-dynamic-in-cloudformation

i couldn't ask more questions there.. so i had to make a new post. sorry..

but now I have more data and its causing some issue.. i think !sub uses ${} to substitute and its colliding with the syntax that bash also uses. anyone here know how to make this template work? either by splitting them using !Join or by simply resolve the place holders i.e. ${}..

        UserData:
          Fn::Base64: 
            !Sub 
            |-
              #!/bin/bash
              timedatectl set-timezone America/New_York
              yum -y update
              yum install -y java-11-amazon-corretto-headless httpd ruby jq policycoreutils-python

              echo "ALL: 10." >> /etc/hosts.allow

              SECRET_BLOB=$(aws secretsmanager get-secret-value --region us-east-1 --secret-id MHCSecret-${BuildEnvironment} --query SecretString --output text)

              run_env=$(echo "$SECRET_BLOB" | jq -r .run_env)
              enc_key=$(echo "$SECRET_BLOB" | jq -r .enc_key)
              eureka_password=$(echo "$SECRET_BLOB" | jq -r .eureka_password)

              EC2_AVAIL_ZONE=$(ec2-metadata -z)
              EC2_AVAIL_ZONE=${EC2_AVAIL_ZONE##* }
              case $EC2_AVAIL_ZONE in
                us-east-1b)
                  srv_num="1"
                  ;;
                us-east-1c)
                  srv_num="2"
                  ;;
              esac

              case $run_env in
                dev)
                  tenant=dev
                  ;;
                qa|qa3)
                  tenant=test
                  ;;
                prod)
                  tenant=prod
                  ;;
              esac

              echo "127.0.0.1  assist-${run_env}${srv_num}.ithor${tenant}.aws.myhealth.com" >> /etc/hosts

              useradd assist
              chage -I -1 -m 0 -M 99999 -E -1 assist
              chmod o+x ~assist
              mkdir -m 775 --context=unconfined_u:object_r:httpd_sys_content_t:s0 ~assist/www
              mkdir -m 775 -p ~assist/spring-boot/conf
              cp -a ~ec2-user/.ssh ~assist/

              cat << EOF > /home/assist/spring-boot/conf/run_env
              run_env=$run_env
              srv_num=$srv_num
              EOF

              cat << EOF > /home/assist/spring-boot/conf/enc_key
              ENCRYPT_KEY=$enc_key
              EOF

              cat << EOF > /home/assist/spring-boot/conf/eureka_password
              SECURITY_USER_PASSWORD=$eureka_password
              SPRING_SECURITY_USER_PASSWORD=$eureka_password
              JHIPSTER_REGISTRY_PASSWORD=$eureka_password
              EOF

              chown -R assist:assist ~assist/

              sed -i -e 's/AllowUsers .*/\0 assist/g' -e 's/AllowGroups .*/\0 assist/g' /etc/ssh/sshd_config
              service sshd reload

              cat << EOF > /etc/httpd/conf.d/assist.conf
              DocumentRoot "/home/assist/www"
              Alias "/common" "/home/assist/www/assets/common"
              Alias "/font" "/home/assist/www/assets/common/lib/bootstrap/font"
              Alias "/fonts" "/home/assist/www/assets/common/lib/bootstrap/fonts"
              Alias "/node_modules" "/home/assist/www/assets/node_modules"
              <Directory "/home/assist/www">
                  Options FollowSymLinks
                  AllowOverride All
                  Require all granted

                  RewriteEngine On
                  RewriteBase /

                  # Don't rewrite files or directories
                  RewriteCond %{REQUEST_FILENAME} -f [OR]
                  RewriteCond %{REQUEST_FILENAME} -d
                  RewriteRule ^ - [L]

                  # Rewrite everything else to index.html to allow html5 state links
                  RewriteRule ^ /index.html [L]
              </Directory>
              EOF

              rm -f /etc/httpd/conf.modules.d/00-dav.conf /etc/httpd/conf.modules.d/00-lua.conf /etc/httpd/conf.modules.d/00-proxy.conf /etc/httpd/conf.modules.d/01-cgi.conf /etc/httpd/conf.modules.d/00-optional.conf /etc/httpd/conf.modules.d/10-proxy_h2.conf /etc/httpd/conf.d/userdir.conf /etc/httpd/conf.d/autoindex.conf
              sed -e '/mpm_prefork/s/^/#/g' -i /etc/httpd/conf.modules.d/00-mpm.conf 
              sed -i '/mpm_event/s/^#//g' -i /etc/httpd/conf.modules.d/00-mpm.conf

              systemctl start httpd.service

              cd /tmp
              wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/latest/install
              chmod +x /tmp/install
              /tmp/install auto
              rm -f /tmp/install
asked a year ago1302 views
1 Answer
0

The reason for this error is in the "EC2_AVAIL_ZONE=${EC2_AVAIL_ZONE##* }" section.
As described in the following document, to avoid treating "${}" as a CloudFromtation function, use "! to prevent "${}" from being treated as a CloudFromtation function, as described in the following document.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html

So if you do the following, the error will be eliminated.

EC2_AVAIL_ZONE=${!EC2_AVAIL_ZONE##* }

Also, there is another part "echo "127.0.0.1 assist-${run_env}${srv_num}.ithor${tenant}.aws.myhealth.com" >> /etc/hosts", but if "${run_env}", "${srv_num }" and "${tenant}" are not CloudFormation functions, you need to add "!" as well. must be added as well.
The following changes would be a good idea.

echo "127.0.0.1  assist-${!run_env}${!srv_num}.ithor${!tenant}.aws.myhealth.com" >> /etc/hosts
profile picture
EXPERT
answered 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