Due to a lot of complexities we currently clone our prod systems into a dev and test environment (each environment is completely isolated). I’ve got Ansible running currently in the dev environment where I’ve built a bunch of plays.
We’re about to deploy the changes made in the dev environment to the test environment - will need to build a new Ansible box - this will have access to the same source control for where the current plays are stored for the dev environment.
The hostnames and IP’s are identical in dev/test and prod (for this project).
In one of the playbooks I need to use the win_lineinfile module to insert/replace a line of code in a web.config file - the code that needs to be inserted I want based upon an environment variable (dev, test or prod) so this play can be used in dev/stage and prod. Each environment would need a different section of code in the web.config file.
E.G dev = devintegration.server.example
test = testintegration.server.example
I’m not too sure on how to go about this…
I’m currently running the plays manually - but my next step is to then build projects and run them via AWX.
Not sure how others do it, but I have vars files called e.g. project_dev.yaml, project_prod.yaml. I load these where needed via include_vars, specifying the file as e.g. “project_{{ env }}.yaml”
Then I specify the environment on the command line using -e, e.g. “-e env=prod”
This has the added advantage of preventing the playbook from running at all if I forget the env variable or if I provide one that doesn’t having a matching vars file.
Plus you can (if you want to) refer to the “env” variable in conditions.
We use a similar setup (in our case the variable is called ‘domain’) with Tower. You can easily specify additional variables with each template you want to run.
In our case, as we have a number of systems that require logins - we use custom credentials, which can supply any variables.
in each environment I have a different inventory and in the inventory, all my groups of hosts are added as child groups of a group which contains group variables for this environment.
Here’s a simplified example.
$ cat dev.inventory
`
dev inventory
[appservers]
host3
host4
[dbservers]
host5
host6
[webservers]
host1
host2
add host groups to environment-specific group for dev
Thanks Jon - that sounds like another good way of doing it. Could you also combine this into a similar method as mentioned by Karl where an environment must be specified otherwise the plays won’t run?
Thinking about this some more - my only concern is a few tasks in the plays depending on the environment - so both methods mentioned above will work fine… I could just have a condition specified in the play for specific tasks.
Is this what you’d normally do?
As an example - in the DEV environment I need to delete a DFS target and re-create it with a different target path - I only want this to be actioned for DEV.
Regardless of whether you do it with groups or or not, you can always define a variable in one environment and not in another and use a “when… is defined” condition or similar to decide whether to do something. If you need more granularity, give the variable different values and test the actual value in your when condition.
For something that could be destructive in a production environment, I suggest you try to find a method that will stop your playbook running at all if you forget something, or make sure your default is the non-destructive path. That’s why I like my env variable, because the playbook can’t run if I forget it altogether. Of course, it still doesn’t help me if I accidentally type “prod” instead of “dev”! I get around that by not running my playbooks directly. Instead I use a script that double checks me if I say “prod”. It’s saved me more than once
I do like the safe guard of specifying the environment when running the play - pretty new to Ansible so mistakes could easily happen.
Do you include the vars file within the playbook sub-directory or within a global inventory sub-directory? E.G inventory → vars → all -->> project_dev.yaml