使用for循环和其它声明的变量在EC2用户数据cloudformation

问题描述 投票:1回答:1

我是新来cloudformation YAML。 我有我需要在启动配置用户数据使用如下:

  UserData:
    Fn::Base64: !Sub 
      - |
        #!/bin/bash -x
        apt-get -y update && apt install -y awscli mysql-client libmysqlclient-dev python-pip
          for item in certs user_prop config log
          do
            echo "... preparing ${item} database and config"
            MYSQL_DB_NAME="ext_as_${item}"
            LOCAL_DB_NAME=$(echo ${item}|tr -d '_')
            LOCAL_DB_FILE="/path/to/db/${LOCAL_DB_NAME}"
            DB_KEY="${item}_db"
            #- set db configuration value
            sed -i "s|${DB_KEY}=.*|${DB_KEY}==mysql://${DB_FQDN}/${MYSQL_DB_NAME}|" /path/to/config.conf
            #- create mysql db
            mysql --defaults-file=${MYSQL_PREF} -e "CREATE DATABASE IF NOT EXISTS $${MYSQL_DB_NAME};"
            #- import local DB schema into MySql if no tables exist
            mysql --defaults-file=$${MYSQL_PREF} --silent --skip-column-names \
            -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '${MYSQL_DB_NAME}';"|grep -e ^0 -q \
            && ./dbcvt -t ${item} -s sqlite:///${LOCAL_DB_FILE} -d mysql://${DB_FQDN}/${MYSQL_DB_NAME} -p ${MYSQL_PREF}
          done
        popd
      - 
        DB_FQDN:
          'Fn::ImportValue': 'OVPNConfigDbEndpoint'

现在的问题是DB_FQDN得到解决,但LOCAL_DB_FILELOCAL_DB_NAMEDB_KEYMYSQL_DB_NAMEMYSQL_PREF没有得到解决。现在的问题是:

  1. 如果我硬编码的其他值,我如何在用户数据的shell脚本利用一个for循环?
  2. 我一定要始终使用FN ::加入由亚历克斯在https://stackoverflow.com/a/54535452/4035062提到? 使用Fn::Join写一个简单的shell脚本似乎相当复杂。
  3. 是什么+意味着!Sub |+
amazon-web-services amazon-cloudformation user-data launch-configuration
1个回答
0
投票

你有没有的问题是,你要像${item}的变量bash shell的内部扩张而Fn::Sub Cloudformation内在功能也解释${item}作为变量扩大。

正如docs提到:

为了字面上写一个美元符号和大括号(qazxsw POI),花括号后面添加一个感叹号(qazxsw POI),如${}。 AWS CloudFormation解决了这个文本!

请记住,但是,在Bash中括号通常是可选的。这就是说,你通常可以简单地改写${!Literal}${Literal}

快速浏览一下你的代码建议,我认为你可以重写它这样,它应该是罚款:

${item}

需要注意的几点很好:

  • 请参阅上需要$item符号的UserData: Fn::Base64: !Sub - | #!/bin/bash -x apt-get -y update && apt install -y awscli mysql-client libmysqlclient-dev python-pip for item in certs user_prop config log do echo "... preparing $item database and config" MYSQL_DB_NAME="ext_as_$item" LOCAL_DB_NAME=$(echo $item | tr -d '_') LOCAL_DB_FILE="/path/to/db/$LOCAL_DB_NAME" DB_KEY="${!item}_db" #- set db configuration value sed -i "s|$DB_KEY=.*|$DB_KEY==mysql://${DB_FQDN}/$MYSQL_DB_NAME|" /path/to/config.conf #- create mysql db mysql --defaults-file=$MYSQL_PREF -e "CREATE DATABASE IF NOT EXISTS $MYSQL_DB_NAME;" #- import local DB schema into MySql if no tables exist mysql --defaults-file=$MYSQL_PREF --silent --skip-column-names \ -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '$MYSQL_DB_NAME';"|grep -e ^0 -q \ && ./dbcvt -t $item -s sqlite:///$LOCAL_DB_FILE -d mysql://${DB_FQDN}/$MYSQL_DB_NAME -p $MYSQL_PREF done popd - DB_FQDN: 'Fn::ImportValue': 'OVPNConfigDbEndpoint' ,因为猛砸否则将扩展该变量DB_KEY没有括号那里。
  • ${!item}的情况下,你当然需要,因为在你确实想要通过${item_db}替代这种情况下使用${DB_FQDN}
  • 还需要注意的是我固定的一些错字你猛砸。你有${DB_FQDN}在2个地方一个错字。

为了您的其他问题:

  • 不,你并不需要使用Fb::Sub。你在看这个问题是关于如果有人出于某种原因没有想插$$。这个回答表明,你可以做到这一点的方法之一。
  • 记号Fn::Join是YAML语言的一个特征。它只是说,让新行的块之后。看到这个YAML Fn::Join
© www.soinside.com 2019 - 2024. All rights reserved.