Here is my current scenario.
You can merge master to production and production to master. However, after every merge, you have to reset the working tree of the folders in question. Here is how you can do this.
git checkout production
git merge --no-commit --no-ff master
git reset /path/to/[.ebextensions and .elasticbeanstalk]/folders
git commit
git push
Also, you may forget to reset after every merge so I suggest you set up a post-merge
hook to do this automatically for the respective branches after every merge.
For this version it's relatively simple. For example:
mkdir HelloWorld # create new directory for project
cd HelloWorld # enter the new directory
git init # create git repository
eb init -p PHP # create new application
echo "<?php echo getenv("ENV_NAME"); ?>" > index.php
git add .gitignore index.php
git commit -m 'Initial commit.'
eb create dev-env # create environment named dev-env
eb create prod-env # create environment named prod-env
eb use dev-env # associate dev-env to current branch (master)
eb setenv ENV_NAME=DEV # set env variable specific to dev-env
git checkout -b production # create production branch and switch to it
eb use prod-env # associate prod-env to the current branch (production)
eb setenv ENV_NAME=PROD # set env variable specific to prod-env
This doesn't save ENV_NAME
anywhere in the local filesystem. The EB CLI changes the live EB instance directly. You may use eb config save
(as suggested by Nick Humrich) to save the environment configuration settings for the current running environment to .elasticbeanstalk/saved_configs/<env-name>.cfg.yml
. Since each environment has its own file, you shouldn't have any conflicts, unless you change one of them in both branches. Another option (see Protecting sensitive informations) would be to add them to .gitignore
.
One way is to have distinct optionsettings files for each environment (branch). The EB CLI can help you with that :-)
Run eb init
from each branch (see below) and choose a different environment name for each one, so you'll end up with 2 distinct .elasticbeanstalk/optionsettings.<env-name>
files. This way you avoid the conflicts on .elasticbeanstalk/
.
mkdir MyApp
cd MyApp
git init .
eb init
NOTE: When it asks you to provide an environment name, choose a name that identifies whether it's a development or production environment.
Enter your AWS Access Key ID (current value is "<redacted>"):
Enter your AWS Secret Access Key (current value is "<redacted>"):
Select an AWS Elastic Beanstalk service region.
Available service regions are:
<redacted>
Select (1 to 8): 1
Enter an AWS Elastic Beanstalk application name
(auto-generated value is "MyApp"): MyApp
Enter an AWS Elastic Beanstalk environment name
(auto-generated value is "MyApp-env"): MyApp-dev
Select an environment tier.
Available environment tiers are:
1) WebServer::Standard::1.0
2) Worker::SQS/HTTP::1.0
Select (1 to 2): 1
Select a solution stack.
Available solution stacks are:
<redacted>
Select (1 to 59): 32
Select an environment type.
Available environment types are:
1) LoadBalanced
2) SingleInstance
Select (1 to 2): 2
Create an RDS DB Instance? [y/n]: n
Attach an instance profile (current value is "[Create a default instance profile]"):
<redacted>
Select (1 to 5): 4
git checkout -b production
eb init
Repeat step 3 but pick a different environment name. This will create distinct .elasticbeanstalk/optionsettings.<env-name>
file.
You should use the same app.config
for both environments. The only thing that may diverge between environments is the option_settings
section. But as far as I know, you can't have different option_settings
per environment, so how can we do it?
Well, that's something I don't have an optimal solution yet, but I'll tell you how I do it. I add all option_name
's I need and use placeholder values, for example:
option_settings:
- option_name: MY_CONFIG
value: CHANGEME
Then later I change their values manually through the AWS Elastic Beanstalk admin panel. Go to Application > Configuration > Software Configuration > Environment Properties
.
Another possibility would be to have a custom script which is run by your container_commands
. This script could identify the EC2 instance by its hostname (or another unique value) and automatically load the environment variables (e.g. source <hostname>.env
).
The only rule you need to obey is this: Your repository MUST NOT contain sensitive informations like credentials, unless you don't care.
For example, an application expects to read RDS credentials via environment variables, so you put them in option_settings
. But you don't want other contributors to see them, do you? The solution I propose using placeholder is convenient on this aspect.