@ET-DC@eyJkeW5hbWljIjp0cnVlLCJjb250ZW50IjoicG9zdF90aXRsZSIsInNldHRpbmdzIjp7ImJlZm9yZSI6IiIsImFmdGVyIjoiIn19@[addtoany buttons="twitter", "linkedin"]
Introduction
Variable scoping can be quite complicated on Ansible and it’s important to know what variable your playbook is going to be using. But sometimes it’s not as easy as it may appear. The documentation on Ansible’s website explains this but I’d like to run you through a scenario we found where this is not what you would expect it to be.
Recently whilst working on a deployment where we had the same role applied to a group of servers twice with different configurations we found it wasn’t working for us. We did a bit of investigation and we found that some of the variable precedence was not behaving as we were expecting it to be.
The scenarios below demonstrate the problem on tests 4 and 5.
Test framework
I’m going to use a simple playbook with a single role which prints a variable content to the screen.
LgrilJzilIDilIAgbWFpbi55bWwK4pSU4pSA4pSAIHJvbGVzCiAgICDilJTilIDilIAgbXktcm9sZQogICAgICAgIOKUnOKUgOKUgCBkZWZhdWx0cwogICAgICAgIOKUgiAgIOKUlOKUgOKUgCBtYWluLnltbAogICAgICAgIOKUlOKUgOKUgCB0YXNrcwogICAgICAgICAgICDilJTilIDilIAgbWFpbi55bWwKCjQgZGlyZWN0b3JpZXMsIDMgZmlsZXM=The contents of main.yml for the role isLS0tCi0gZGVidWc6CiAgICB2YXI6IGRheV9vZl90aGVfd2Vlaw==and defaults/main.yml hasLS0tCmRheV9vZl90aGVfd2VlazogVGh1cnNkYXk=
Test 1: Load the role
Playbook
LSBob3N0czogYWxsCiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGU=Result: ThursdayExplanation: It simply takes the default value from the role
Test 2: Override the default with a new value
LSBob3N0czogYWxsCiAgdmFyczoKICAgIGRheV9vZl90aGVfd2VlazogTW9uZGF5CiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGU=Result: MondayExplanation: New value displayed as expected
Test 3: Override variable from within the role
LSBob3N0czogYWxsCiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGUKICAgICAgdmFyczoKICAgICAgICBkYXlfb2ZfdGhlX3dlZWs6IE1vbmRheQ==Result: MondayExplanation: New value displayed as expected
Test 4: Load the role twice and change the default value for one of them
LSBob3N0czogYWxsCiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGUKICAgICAgdmFyczoKICAgICAgICBkYXlfb2ZfdGhlX3dlZWs6IE1vbmRheQogICAgLSBuYW1lOiBteS1yb2xlResult: Monday is displayed twice, one for each roleExplanation: This is an unexpected result. You would have thought it the result would be Thursday for the first time the role loads and Monday for the second attempt but Ansible seems to override the value.
Test 5: Change the order of loading from Test 4
LSBob3N0czogYWxsCiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGUKICAgIC0gbmFtZTogbXktcm9sZQogICAgICB2YXJzOgogICAgICAgIGRheV9vZl90aGVfd2VlazogTW9uZGF5Result: Monday is displayed twice, one for each roleExplanation: This is another unexpected result. Logic would dictate that the first one should be Thursday and Monday for the second attempt. The order in which the roles are defined does not affect the result.
Test 6: Override value for both roles
LSBob3N0czogYWxsCiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGUKICAgICAgdmFyczoKICAgICAgICBkYXlfb2ZfdGhlX3dlZWs6IE1vbmRheQogICAgLSBuYW1lOiBteS1yb2xlCiAgICAgIHZhcnM6CiAgICAgICAgZGF5X29mX3RoZV93ZWVrOiBUdWVzZGF5Result: Monday and TuesdayExplanation: This is exactly what you would expect as you’re changing the default value.
Test 7: Set global variable and override on role
LSBob3N0czogYWxsCiAgdmFyczoKICAgIGRheV9vZl90aGVfd2VlazogRnJpZGF5CiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGUKICAgIC0gbmFtZTogbXktcm9sZQogICAgICB2YXJzOgogICAgICAgIGRheV9vZl90aGVfd2VlazogVHVlc2RheQ==Result: Tuesday on both outputExplanation: This is yet another unexpected result similar to tests 4 and 5. The local variable set for a single role seems to override the whole playbook.
Test 8: Override variable from command line
LSBob3N0czogYWxsCiAgdmFyczoKICAgIGRheV9vZl90aGVfd2VlazogRnJpZGF5CiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGUKICAgIC0gbmFtZTogbXktcm9sZQogICAgICB2YXJzOgogICAgICAgIGRheV9vZl90aGVfd2VlazogVHVlc2RheQ==
and we’re running the playbook using
YW5zaWJsZS1wbGF5Ym9vayAtaSBsb2NhbGhvc3QsIAogIC0tY29ubmVjdGlvbj1sb2NhbCAKICAtdiBtYWluLnltbCAKICAtZSBkYXlfb2ZfdGhlX3dlZWs9WWVzdGVyZGF5Result: YesterdayExplanation: Ansible documentation states that the command line has the highest precedence and it stands to reason that all the other variables are ignored.
Test 9: Change variable with set_fact
LSBob3N0czogYWxsCiAgdmFyczoKICAgIGRheV9vZl90aGVfd2VlazogRnJpZGF5CiAgcHJlX3Rhc2tzOgogICAgLSBzZXRfZmFjdDoKICAgICAgICBkYXlfb2ZfdGhlX3dlZWs6IFdlZG5lc2RheQogIHJvbGVzOgogICAgLSBuYW1lOiBteS1yb2xlCiAgICAgIHZhcnM6CiAgICAgICAgZGF5X29mX3RoZV93ZWVrOiBNb25kYXkKICAgIC0gbmFtZTogbXktcm9sZQogICAgICB2YXJzOgogICAgICAgIGRheV9vZl90aGVfd2VlazogVHVlc2RheQ==Result: Wednesday for both rolesExplanation: This is expected as set_fact has precedence over roles.
Test 10: Import variable from files
The day_of_the_week variable is move into two files, one defines Wednesday and loaded first and the other one sets the value of Friday and it’s loaded last
LSBob3N0czogYWxsCiAgdmFyc19maWxlczoKICAgIC0gd2VkLnltbAogICAgLSBmcmkueW1sCiAgcm9sZXM6CiAgICAtIG5hbWU6IG15LXJvbGU=Result: Friday Explanation: This is expected. The last value overrides the first one.
Summary
Some of the results where surprising to me.
Sergio has many years experience working on various development projects before joining Digitalis. He worked for large companies with complex networks and infrastructure. ‘This has helped Sergio gain lots of experience in multiple areas from programming to networks. He especial excels is in DevOps: automation is his day-to-day and Kubernetes his passion.