Использование цикла for и других объявленных переменных в облачной информации пользовательских данных ec2 - PullRequest
0 голосов
/ 08 февраля 2019

Я новичок в облачной информации 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_NAME, DB_KEY, MYSQL_DB_NAME и MYSQL_PREF не разрешаются.Теперь вопросы:

  1. Если я жестко закодирую другие значения, как мне использовать цикл for в сценарии оболочки userdata?
  2. Должен ли я всегда использовать Fn :: Join, как упомянуто Алексом в https://stackoverflow.com/a/54535452/4035062?
    Использование Fn::Join для написания простого сценария оболочки кажется довольно сложным.
  3. Что означает + в !Sub |+?

1 Ответ

0 голосов
/ 08 февраля 2019

Проблема, с которой вы столкнулись, заключается в том, что вы хотите, чтобы переменные типа ${item} были развернуты внутри оболочки Bash, тогда как встроенная функция Fn::Sub Cloudformation также интерпретирует ${item} как переменную для расширения.

Как указано в документах :

Чтобы буквально написать знак доллара и фигурные скобки (${}), добавьте восклицательный знак (!) после открытой фигурной скобки, например ${!Literal}.AWS CloudFormation разрешает этот текст как ${Literal}.

Однако имейте в виду, что скобки в Bash обычно необязательны.То есть обычно вы можете переписать ${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}, поскольку Bash в противном случае расширил бы переменную ${item_db} без фигурных скобоктам.

  • В случае ${DB_FQDN} вам, конечно, нужно использовать ${DB_FQDN}, потому что в этом случае вы хотите заменить на Fb::Sub.

  • Обратите внимание, что я исправил некоторые опечатки в вашем Bash.У вас есть $$ в качестве опечатки в 2 местах.

На другие ваши вопросы:

  • Нет, вам не нужно использовать Fn::Join.Тот вопрос, на который вы смотрели, был о том, хочет ли кто-то по какой-то причине интерполировать Fn::Join.Этот ответ показывает, как вы можете это сделать.

  • Обозначение |+ является особенностью языка YAML.Это просто говорит, чтобы сохранить переводы строк после блока.Посмотреть этот YAML шпаргалка .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...