用于 EC2 Image Builder 的 yaml 中的多行 bash 脚本

Posted

技术标签:

【中文标题】用于 EC2 Image Builder 的 yaml 中的多行 bash 脚本【英文标题】:Multi-line bash script in yaml for EC2 Image Builder 【发布时间】:2021-01-06 19:50:37 【问题描述】:

我正在尝试创建自定义组件文档。虽然我使用各种 yaml linters 测试了 yaml 文件,但 EC2 Image builder 抱怨以下错误

Failed to create component. Fix the error(s) and try again:
The value supplied for parameter 'data' is not valid. Parsing step 'Configuremysql' in phase 'build' failed. Error: line 4: cannot unmarshal map into string.

而且我无法弄清楚我的 yaml 文件出了什么问题

name: MyJavaAppTestDocument
description: This is JavaApp Document
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: InstallSoftware
        action: ExecuteBash
        inputs:
          commands:
            - sudo yum update -y
            - sudo yum install -y java-1.8.0
            - sudo amazon-linux-extras install -y tomcat8.5
            - sudo yum install -y https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
            - sudo yum install -y mysql-community-server
      
      - name: ConfigureTomcat
        action: ExecuteBash
        inputs:
          commands:
            - sudo sed -i 's/<\/tomcat-users>/\n<role rolename="manager-gui"\/>\n  <role 
              rolename="manager-script"\/>\n  <role rolename="admin-gui"\/>\n  <user username="admin" 
              password="admin" roles="manager-gui,manager-script,admin-gui"\/>\n<\/tomcat-users>/' 
              /etc/tomcat/tomcat-users.xml
            - sudo systemctl start tomcat
            - sudo systemctl enable tomcat
      
      - name: ConfigureMySQL
        action: ExecuteBash
        inputs:
          commands:
            - sudo systemctl start mysqld
            - sudo systemctl enable mysqld
            - mysqlpass=$(sudo grep 'temporary password' /var/log/mysqld.log | sed 's/.*root@localhost: //')
            - mysql -u root -p$mysqlpass --connect-expired-password -h localhost -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'whyDoTh1s@2020'"
            - |
              sudo cat <<EoF > /tmp/mysql-create-user.sql
              CREATE USER 'admin'@'%' IDENTIFIED BY 'whyDoTh1s@2020';
              GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION;
              EoF

            - sudo mysql -u root -pwhyDoTh1s@2020 -h localhost < /tmp/mysql-create-user.sql

如果有人可以帮助我找出错误,我将不胜感激。目标是使用预配置的软件和设置构建 AMI。

【问题讨论】:

您解决了这个问题吗? @Aashish Jolly 【参考方案1】:

由于此行中的 :,您会收到该错误:

- mysqlpass=$(sudo grep 'temporary password' /var/log/mysqld.log | sed 's/.*root@localhost: //')

YAML 解析器将该行解释为创建映射,而不是在现有映射中创建字符串条目。我可以在自己的 YAML 中使用的一种解决方法是用单引号将 : 括起来,这样问题行就会变成

- mysqlpass=$(sudo grep 'temporary password' /var/log/mysqld.log | sed 's/.*root@localhost':' //')

根据我自己的使用和this online YAML parser,我使用该解决方案进行了测试,应该可以解决问题。

【讨论】:

【参考方案2】:

虽然@micah-l-c 的回答可以帮助 OP 的情况。

我会建议一种替代方法,它也可以帮助并且可以更正确地解决这个问题。

这里是错误的行

- mysqlpass=$(sudo grep 'temporary password' /var/log/mysqld.log | sed 's/.*root@localhost: //')

这可以改写为

- |-
    mysqlpass=$(sudo grep 'temporary password' /var/log/mysqld.log | sed 's/.*root@localhost: //')

- >-
    mysqlpass=$(sudo grep 'temporary password' /var/log/mysqld.log | sed 's/.*root@localhost: //')

现在: 将通过上述方法很好地转义。

我遇到了类似的问题,我将举一个例子,说明@micah-l-c 解决方案不起作用,而上述方法工作正常。

下面是我在 ec2 图像构建器组件中添加的行

- echo "user1    ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers

我在 : 周围加上了单引号,它使 /etc/sudoers 格式错误,因此它不起作用。

我像这样替换上面的行

- |-
    echo "user1    ALL=(ALL)       NOPASSWD: ALL" >> /etc/sudoers

参考资料:

How to escape indicator characters (i.e. : or - ) in YAML

【讨论】:

这是一个更好、更通用的答案:)

以上是关于用于 EC2 Image Builder 的 yaml 中的多行 bash 脚本的主要内容,如果未能解决你的问题,请参考以下文章

通过Terraform aws ec2 import-image

Flutter 应用程序,ListView.builder 首次运行时出现错误。需要重启应用(ListView.builder 和 image_picker)

php facetwp woocommerce image + sale html for layout builder

Openstack 之 使用disk-image-builder(DIB)制作镜像

Lambda 不适用于具有自动缩放功能的 ec2

aws imagebuilder 理解并使用imagebuilder构建pcluster自定义ami