Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to differentiate between staging/production with a dynamic inventory?

I'm stuck. Googled the hell out of the Web and couldn't find an answer.

I've been using Ansible for years, but always with static inventories. To differentiate between different environments like staging and production, I used different static inventory files, staging and production, respectively. When I needed to provision staging servers, I'd do:

ansible-playbook site.yml -i staging

When I wanted to do the same for production, I'd do:

ansible-playbook site.yml -i production

Both staging and production need variables with different values, so I have group_vars/staging and group_vars/production. All good and according to best practices.

Now, I need to provision EC2 instances in AWS. I'm using this AWS guide. I have a playbook with two plays. The first is run against localhost, creates/finds required EC2 instances in AWS, and populates a group with add_host. The second play uses that group to run against the EC2 instances discovered in the first play. All according to that guide.

It all works great except one thing. I have no idea how to specify which environment to provision and hence the required variables are not being loaded from group_vars/(staging|production). Basically, what I want is something similar to -i (staging|production) I used all these years with static inventories, but it seems that using -i doesn't make sense now since the inventory is dynamic. I want a way to be able to load variables from either group_vars/staging or group_vars/production based on an argument I pass to ansible-playbook when I run it.

How do I do that? What's the best practice?

like image 865
Elnur Abdurrakhimov Avatar asked Mar 03 '16 17:03

Elnur Abdurrakhimov


1 Answers

While I am not sure how to do it with ansible EC2 moduel as we don't use it to build boxes from ansible level, there is a simple way to get what you want with ec2 external inventory script and simple settings in your inventories/main. What you need to do is set up the ec2.py and ec2.ini inside of your inventories so it will be used as source of instances. Make sure to uncomment group_by_tag_keys = True inside of ec2.ini.

Next step is to differentiate which instance goes where. While there are many selection methods available in ec2.py, I prefer to specifically tag each instance accordingly. So all my instances have a tag called environment which is filled accordingly (in your case it would be either staging or production). Then all is left is to handle it inside of your inventories/main, and here is a small example how to do it.

First you must define empty group for tags you want to use:

[tag_environment_staging]

[tag_environment_production]

so we can later reference to them. After that all there is left to do is specify those groups as children for appropriate stages. So after that our minimal file will look like that:

[tag_environment_staging]

[tag_environment_production]

[staging:children]
tag_environment_staging

[production:children]
tag_environment_production

And there you go. From now on every instance pulled from ec2 via dynamic inventory script that comes with environment tag will be matched to appropriate config in group_vars. All you have to remember that when dealing with dynamic inventories you want your -i point at inventories directory rather than specific file for it to work right.

like image 169
Tymoteusz Paul Avatar answered Sep 24 '22 00:09

Tymoteusz Paul