Elastic Beanstalk configuration using ebextensions container_commands combining leader_only and test For our Django app running on AWS Elastic Beanstalk, we use a web-server/worker setup. The same code is deployed to the web-server and worker environments, and environment-specific configuration is achieved with .ebextensions config files, using the test option for container_commands, among other things.

Now there are some container commands we would like to execute only during deployment or environment-creation (so we use leader_only: true, see bottom), but, in addition, they should never be executed on the worker environment. 

The latter could be achieved using the test option, but that cannot be used not in combination with leader_only, according to the docs:


  ... A command can be leader-only or have a test, but not both (leader_only takes precedence).


Now, to work around this, we do something like the following, in .ebextensions/foo.config:

option_settings:
  aws:elasticbeanstalk:application:environment:
    ENV_NAME: '`{ "Ref" : "AWSEBEnvironmentName" }`'  # get the current environment name

container_commands:
  0100_set_flag_if_instance_is_leader:
    command: touch /tmp/is_leader  # create empty file
    leader_only: true
  0200_execute_command_on_leader_only_but_never_on_worker:
    command: foo bar
    test: '[[ $ENV_NAME != "worker" &amp;&amp; -e /tmp/is_leader ]]'


where ENV_NAME contains the environment name, which is automatically retrieved with the help of option_settings (see docs).

Note that the config file is in YAML format and the commands and tests execute in a shell (I assume bash, since the extended test construct [[ works, but could not find any specifics in the AWS docs).

As I am not an expert, I would really appreciate your comments on the following points:


The solution above works, but is this the simplest way to do it?
Are there any compelling reasons not to use this kind of set-up?
I tried setting a variable instead of creating a file (in command 0100), but the variable does not appear to persist between container commands. Is there some way to achieve this? (I tried to export, but that didn't help. Is each container command executed in a separate shell, or how does this work?)


Some general background from the AWS docs:


  You can use leader_only to only run the command on a single instance, or configure a test to only run the command when a test command evaluates to true. Leader-only container commands are only executed during environment creation and deployments, while other commands and server customization operations are performed every time an instance is provisioned or updated. Leader-only container commands are not executed due to launch configuration changes, such as a change in the AMI Id or instance type.
It turns out there is an environment variable called EB_IS_COMMAND_LEADER which can be used in a test. See e.g. this post on AWS forums.
So, the two container commands from the OP can be replaced by this:
container_commands:
  0100_execute_command_on_leader_only_but_never_on_worker:
    command: foo bar
    test: '[[ $ENV_NAME != &quot;worker&quot; &amp;&amp; $EB_IS_COMMAND_LEADER == &quot;true&quot; ]]'

I believe this environment variable is only available during deployment, although I could not find any documentation.
NOTE: The original question was aimed at Amazon Linux AMI (AL1), which is now deprecated. In the new Amazon Linux 2 we can use shell scripts in .platform/hooks/ as an alternative to container_commands. The EB_IS_COMMAND_LEADER variable can be used there as well.