特定于环境的 ebextensions Beanstalk 命令

Environment specific ebextensions Beanstalk commands

我有一个 spring-boot 应用程序,我需要为其指定 Graphite 服务器和端口(以发送指标)。为此,我必须安装和配置 statsd。我使用 ebextensions 文件来做到这一点。

commands:
  01_nodejs_install:
    command: sudo yum -y install nodejs npm --enablerepo=epel
    ignoreErrors: true

  02_mkdir_statsd:
    command: mkdir /home/ec2-user/statsd
    ignoreErrors: true

  03_fetch_statsd:
    command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
    ignoreErrors: true

  04_change_example_config:
    command: "cat exampleConfig.js | sed 's/2003/<graphite-port>/g' | sed 's/graphite.example.com/<my-graphite-server>/g' > config.js"
    cwd: /home/ec2-user/statsd

  05_run_statsd:
    command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
    cwd: /home/ec2-user/statsd

这个配置的问题是我在这里只能为所有环境指定 1 个石墨服务器。

所以我决定将命令 04 和 05 移动到 container_commands。我正在考虑使用 beantalk console/UI 定义一个名为 ENV_NAME 的环境变量,并将其设置为 devqaprod根据环境。然后我可以使用 container_commandstest 选项到 运行 04 和 05 命令仅用于基于此 ENV_NAME.

的特定环境

所以我的问题是 - 如何使用 AWS 控制台定义环境变量?我尝试使用 Beanstalk 控制台来定义我的变量,如文档 here but it did not work. I also found 中所述(请参阅有 5 个赞成票的答案)该方法仅设置 JVM 属性而不设置 ENV 变量。

我无法使用 ebextensions 定义环境变量,因为那样我会遇到同样的问题 - 无法为不同的环境定义不同的环境变量 :)

所以我需要帮助:

  • 使用 beanstalk UI 设置 ENV_NAME 环境变量。

  • 建议在container_commands中使用ENV_NAME系统属性来根据ENV_NAME的值判断是否运行命令.

如果您知道 simpler/better 为不同环境指定不同 Graphite 服务器的方法,请随时参与。

答案就在这个Springdocumentation中,但我会用我的话说一点: 由于您正在 运行 启动 spring 启动应用程序,因此您可以创建不同的 'application.properties' 文件,如下所示:

在每个文件中,您可以放置​​石墨(或其他)配置:

在我的申请中-dev.yml:

在我的申请中-prod.yml:

如您所见,每个环境都有一个配置。

您可以 运行 您的应用程序具有不同的 maven 配置文件,在这种情况下,假设:dev 和 prod...在我的例子中,我的 'dev' 配置文件是默认设置的,所以当应用程序启动它将加载开发配置文件,因此,应用程序-dev.yml 配置。

我的pom.xml

片段
<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            ...

然后,当您 运行 您的应用程序具有每个配置文件时,它将加载所需的 .yml 文件

让我们看看,如果我 运行:

java -jar mywar.war

我的控制台加载开发配置文件(因为记住它是我的默认配置文件)

但是如果我指定产品配置文件,例如:

java -jar mywar.war --spring.profiles.active=prod

我的控制台将显示:

要在 Elastic Beanstalk 中设置环境变量,请转到配置 -> 软件配置:

并设置spring.profile.active,像这样:

最后一条评论:不要混淆环境属性和环境标签!

  • 环境属性:我刚刚向您展示的那些:环境变量。
  • 环境标签:资源的 Elastic Beanstalk 标签,如前所述 here

我解决这个问题的方法是在 dev 和 prod 环境中分别将 ENV_NAME 定义为 devprod,并使用以下 ebextensions 配置。

commands:
  01_nodejs_install:
    command: sudo yum -y install nodejs npm --enablerepo=epel
    ignoreErrors: true

  02_mkdir_statsd:
    command: mkdir /home/ec2-user/statsd
    ignoreErrors: true

  03_fetch_statsd:
    command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
    ignoreErrors: true

container_commands:
  04a_container_change_example_config:
    command: "cat exampleConfig.js | sed 's/2003/<graphite-dev-port>/g' | sed 's/graphite.example.com/<graphite-dev-host>/g' > config.js"
    cwd: /home/ec2-user/statsd
    test: '[ "${ENV_NAME}" == "dev" ]'

  04b_container_change_example_config:
    command: "cat exampleConfig.js | sed 's/2003/<graphite-prod-port>/g' | sed 's/graphite.example.com/<graphite-prod-host>/g' > config.js"
    cwd: /home/ec2-user/statsd
    test: '[ "${ENV_NAME}" == "prod" ]'

  05_run_statsd:
    command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
    cwd: /home/ec2-user/statsd

使用 test 我可以在我已经在 beantalk 环境中定义的 ENV_NAME 属性 上调节 container command 的执行。

除了@Nik 的回答:

除了手动添加环境变量 ENV_NAME,您还可以获取实际的环境名称并将其自动存储在 ENV_NAME 中。这是在 ebextensions 配置文件中使用 option_settings 实现的。

例如:

option_settings:
  aws:elasticbeanstalk:application:environment:
    ENV_NAME: '`{ "Ref" : "AWSEBEnvironmentName" }`'  # assign the actual env name to ENV_NAME

container_commands:
  0100_execute_only_in_dev:
    command: echo "this is the development environment"  # this will turn up in ebactivity.log
    test: '[[ $ENV_NAME = "dev" ]]'

旁注,对于那些像我这样不太熟悉 shell 脚本的人:测试表达式中的空格很重要 ().

更新:亚马逊Linux 2

自 2021 年起,Amazon Linux 2 is the new standard. Amazon Linux 2 uses platform hooks 而不是 .ebextensions 中的 container_commands

这里有一个 bash 脚本,等同于上面定义的 0100_execute_only_in_dev 容器命令,可以用作亚马逊上的平台挂钩 Linux 2:

0100_execute_only_in_dev.sh

#!/bin/bash
if [ $ENV_NAME = "dev" ]
# the following output will end up in "/var/log/eb-hooks.log"
then echo "this is the development environment" 
fi

shell 脚本需要执行权限,如 here, and can be placed in any of the subdirectories of .platform/hooks and/or .platform/confighooks, in your source bundle, depending on the applicable deployment phase (prebuild, predeploy, or postdeploy). See the deployment workflow 所述以获取更多信息。它还有助于检查 /var/log/eb-engine.log,以了解部署期间到底发生了什么。

请注意,平台挂钩也可以访问 EB 环境属性。