<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Louwrentius - Infrastructure</title><link href="https://louwrentius.com/" rel="alternate"/><link href="https://louwrentius.com/feeds/infrastructure.atom.xml" rel="self"/><id>https://louwrentius.com/</id><updated>2026-06-03T12:00:00+02:00</updated><entry><title>DNS is for people - not for IT infrastructure</title><link href="https://louwrentius.com/dns-is-for-people-not-for-it-infrastructure.html" rel="alternate"/><published>2026-06-03T12:00:00+02:00</published><updated>2026-06-03T12:00:00+02:00</updated><author><name>Louwrentius</name></author><id>tag:louwrentius.com,2026-06-03:/dns-is-for-people-not-for-it-infrastructure.html</id><summary type="html">&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Domain_Name_System"&gt;Domain Name System&lt;/a&gt; exists because it's difficult for people to remember IP addresses (185.15.59.224) and much easier to remember domain names (wikipedia.org). &lt;/p&gt;
&lt;p&gt;Regarding internet-accessible services, it makes sense to publish websites, API endpoints or similar services using DNS, as people have to interfact with them …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Domain_Name_System"&gt;Domain Name System&lt;/a&gt; exists because it's difficult for people to remember IP addresses (185.15.59.224) and much easier to remember domain names (wikipedia.org). &lt;/p&gt;
&lt;p&gt;Regarding internet-accessible services, it makes sense to publish websites, API endpoints or similar services using DNS, as people have to interfact with them. 
The added benefit of a domain name is that the associated IP address can change without the client being affected.&lt;/p&gt;
&lt;p&gt;This article isn't against DNS for public services, but it questions if we should use DNS for internal IT infrastructure (independent of cloud vs. onprem)&lt;/p&gt;
&lt;h2&gt;It's always DNS&lt;/h2&gt;
&lt;p&gt;Although DNS can be a very beneficial service, it can also become a liability. If you want a reliable system, you want as little components as possible. Every additional component adds a potential risk of failure. In addition, more components may create unforeseen behaviour and interactions that can cause outages (circular dependancies, and so on). If you can avoid adding components, you'll have a better chance of building a reliable system.&lt;/p&gt;
&lt;p&gt;Within the IT operations space, DNS has made a bit of a name for itself. Many may remember this little haiku.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;It’s not DNS
There’s no way it’s DNS
It was DNS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.reddit.com/r/sysadmin/comments/4oj7pv/comment/d4czk91/"&gt;(source)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/2021_Facebook_outage"&gt;multiple(1)&lt;/a&gt; &lt;a href="https://aws.amazon.com/message/101925/"&gt;high-profile(2)&lt;/a&gt; incidents where DNS was involved. In these linked cases, the root-cause of the incident isn't the DNS system itself. Yet, because the root-cause affects the DNS service - which is in the critical path for virtually all services - the incident has such a huge impact.&lt;/p&gt;
&lt;p&gt;The Facebook / Meta outage was so significant because it locked people out of buildings (physical access) due to 'circular' dependancies on DNS being available. Again, it can be said that the circular dependancy is the root-cause, but the blast radius of DNS is in many cases so enormous that it may be difficult to have a clear end-to-end picture of potential risk.&lt;/p&gt;
&lt;h2&gt;The case against DNS for internal IT infrastructure&lt;/h2&gt;
&lt;p&gt;From the perspective of IT operations, DNS has a drawback: DNS clients cache DNS records based on TTL. Different DNS client implementations can behave differently, but even if you have a fairly homogenous environment, the only way to assure clients (in this case other servers) use the updated IP address, is to control them and force a DNS refresh. &lt;/p&gt;
&lt;p&gt;That got me thinking, why would we use DNS for infrastructure services? It isn't necessary for machine-to-machine communication. Instead of configuring domain names that may not resolve, we can just directly inject the appropriate IP address(ess) into configuration files. It's easy to configure systems with tools like Ansible or pyinfra at scale.&lt;/p&gt;
&lt;p&gt;The counter argument could be that DevOPS / platform engineers are also humans, and it's much easier to spot misconfigurations or to troubleshoot if domain names are configured Instead of IP addresses. &lt;/p&gt;
&lt;p&gt;Fortunately, we still have &lt;code&gt;/etc/hosts&lt;/code&gt;, which we can easily provision. Still no DNS service required! This way, we can configure domain names and pretend to use DNS. I also suspect that DNS queries against /etc/hosts are quite responsive.&lt;/p&gt;
&lt;h2&gt;DNS as generic security risk&lt;/h2&gt;
&lt;p&gt;As of today, most network traffic is encrypted by default, or tunneled through an encrypted channel. DNS is - by default - the exception. Regarding internal IT infrastructure (cloud or 'onprem'), the network may be considered as a secure environment. An attack on the DNS service, spoofing packets, and so on, can be very disruptive though. Setting up DNSSEC may alleviate this problem, but that also introduces another administrative burden with it's own risk of misconfiguration. It's yet another layer of complexity. And we assume that internal infrastructure supports DNSSEC.&lt;/p&gt;
&lt;h2&gt;DNS as an Egress Exfiltration risk&lt;/h2&gt;
&lt;p&gt;Because &lt;a href="https://en.wikipedia.org/wiki/Egress_filtering"&gt;egress filtering&lt;/a&gt; (filtering of outbound connections) can be cumbersome, it's often omitted, because the systems involved are 'trusted'. This is unfortunate as this makes life easier for an attacker. Any kind of resource required for an attack can be acquired on the vulnerable system with a simple outbound query towards the internet. Proper egress filtering of network traffic can be the difference between a succesfull and unsuccessful hacking attempt.&lt;/p&gt;
&lt;p&gt;A lack of egress filtering also makes it much easier for an attacker to exfiltrate data. And the thing is: any IP protocol can be used to exfiltrate data, including DNS&lt;sup id="fnref:others"&gt;&lt;a class="footnote-ref" href="#fn:others"&gt;1&lt;/a&gt;&lt;/sup&gt;. &lt;/p&gt;
&lt;p&gt;This is how: the attacker gets a domain runs their internet-accessible authoritative nameserver for this domain. Now the attacker can make DNS requests to said domain like sensitivedata.evil.domain from the hacked system and you can extract all the data from the rogue DNS server logs&lt;sup id="fnref:exf"&gt;&lt;a class="footnote-ref" href="#fn:exf"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Although a hacked server may not be able to directly interact with the attacker-controlled DNS server, by issuing DNS requests for the attacker-controlled domain, these requests will pass the local forwarding DNS server and be forwarded towards the attacker-controlled authoritative DNS server. See also tools like &lt;a href="https://github.com/iagox86/dnscat2"&gt;dnscat2&lt;/a&gt; or &lt;a href="https://code.kryo.se/iodine/"&gt;iodine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Due to this risk, there is a case to be made, to - at least - not allow systems to query public DNS records. As servers may need to interfact with services on the internet (update servers, APIs, and so on), such access can be facilitated by a proxy server using allow-listed domains.&lt;/p&gt;
&lt;h2&gt;Evaluation and closing words&lt;/h2&gt;
&lt;p&gt;In the end, everything is a tradeoff, where people must balance benefits and drawbacks against the context of their infrastructure, their particular risk appetite and even organisational structure and culture. &lt;/p&gt;
&lt;p&gt;That said, I think it's reasonable to explore if DNS can be avoided altogether within the IT infrastructure to increase reliability and robustness. &lt;/p&gt;
&lt;p&gt;Feel free to share your thoughts and feelings about this if you feel so inclined. Maybe leave a comment on the &lt;a href="https://news.ycombinator.com/item?id=48391957"&gt;Hacker News thread&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Postscript on HN response (update)&lt;/h2&gt;
&lt;p&gt;Update: I do find the responses on the HN thread very interesting from an antropological perspective. How people respond and what implicit assumptions they make. One thing that I found interesting is how many people implicitly assume an environment is 'kubernetes-like', and they focus on 'service discovery'. Problems do arise if you have many IP address mutations for your infrastructure, especially at scale. Because I was thinking about very old-fashioned virtual machine or bare-metal style environment at a small to medium scale (a scale that is much more common I believe, most environments aren't Facebook/Google or even 1/100000 that size).&lt;/p&gt;
&lt;p&gt;I realised that I should have given more context in this article, under which conditions I think my 'DNS alternative' could work well and acknowledge where it would not. Anyway, acknowledging my fault for not creating enough context, I do find the knee-jerk responses, hostility and sometimes personal attacks curious. Only &lt;em&gt;very few&lt;/em&gt;* people seem to pause, stay calm, think about my article, and acknowledge that it could work, within specific circumstances. Also many skipped a core part of the article which was thinking about risk and complexity, in some sense it wasn't only about DNS. &lt;/p&gt;
&lt;p&gt;I also just realise that I made a very important mistake. Servers hosting applications don't need DNS resolving for the internet. I got a feeling from some responses that I was proposing that /etc/hosts would be updated with thousands of DNS records for external internet-facing services. I was only talking about internal infrastructure where internal services, like other servers, or NTP, SMTP, or whatever is configured. I think I did address this assumption in the article, but not nearly explicitly enough.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:others"&gt;
&lt;p&gt;Don't forget about services like NTP or ICMP.&amp;#160;&lt;a class="footnote-backref" href="#fnref:others" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:exf"&gt;
&lt;p&gt;I have demonstrated this attack using this exact method with a domain I own for a customer that thought they had properly prevented egress traffic, including blocking NTP and ICMP.&amp;#160;&lt;a class="footnote-backref" href="#fnref:exf" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Infrastructure"/></entry><entry><title>Improve privacy by running a DNS server without forwarder</title><link href="https://louwrentius.com/improve-privacy-by-running-a-dns-server-without-forwarder.html" rel="alternate"/><published>2026-03-25T12:00:00+01:00</published><updated>2026-03-25T12:00:00+01:00</updated><author><name>Louwrentius</name></author><id>tag:louwrentius.com,2026-03-25:/improve-privacy-by-running-a-dns-server-without-forwarder.html</id><summary type="html">&lt;p&gt;&lt;strong&gt;Disclaimer: no AI was used to write this article.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you run a DNS server at home or for an organisation, it is likely that you configured a public DNS server as a forwarder&lt;sup id="fnref:public"&gt;&lt;a class="footnote-ref" href="#fn:public"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is not required!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Imagine we want to resolve the address 'wikipedia.org'.&lt;/p&gt;
&lt;p&gt;If no …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Disclaimer: no AI was used to write this article.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you run a DNS server at home or for an organisation, it is likely that you configured a public DNS server as a forwarder&lt;sup id="fnref:public"&gt;&lt;a class="footnote-ref" href="#fn:public"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is not required!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Imagine we want to resolve the address 'wikipedia.org'.&lt;/p&gt;
&lt;p&gt;If no forwarder is configured, a DNS server will behave like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Query the &lt;a href="https://en.wikipedia.org/wiki/Root_name_server"&gt;root server&lt;/a&gt;&lt;sup id="fnref:cluster"&gt;&lt;a class="footnote-ref" href="#fn:cluster"&gt;3&lt;/a&gt;&lt;/sup&gt; for an IP address of the .org &lt;a href="https://en.wikipedia.org/wiki/Top-level_domain"&gt;top-level domain&lt;/a&gt; authoritative DNS server&lt;/li&gt;
&lt;li&gt;Query the .org DNS server for an IP address of the wikipedia.org &lt;a href="https://superuser.com/questions/370105/what-does-authoritative-dns-server-mean"&gt;authoritative&lt;/a&gt; DNS server&lt;/li&gt;
&lt;li&gt;Query the wikipedia.org DNS server for the IP address of 'wikipedia.org'&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is what the forwarder does when you query a domain that is not cached by said forwarder.&lt;/p&gt;
&lt;h3&gt;A forwarder responds faster?!&lt;/h3&gt;
&lt;p&gt;Yes, that's probably true, but I think it doesn't matter.&lt;/p&gt;
&lt;p&gt;As a DNS forwarder caches DNS lookups, it will respond directly with the appropriate IP address. Only a single DNS query is required. &lt;/p&gt;
&lt;p&gt;Without a forwarder, a domain lookup that is not cached, will require at least two or three DNS queries, the first time this domain is resolved. After this first set of queries, the domain is cached for the duration of the &lt;a href="https://en.wikipedia.org/wiki/Time_to_live#DNS_records"&gt;TTL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I've performed a few manual lookups with 'dig' for domains that aren't cached, and most responses are &amp;lt;50ms. Depending on where you live and the quality of the network connection (in terms of latency) it may or may not be noticable, that's up to you to explore.&lt;/p&gt;
&lt;h3&gt;So what is the privacy angle?&lt;/h3&gt;
&lt;p&gt;You are exposing privacy-sensitive information to Google or other large companies.&lt;/p&gt;
&lt;p&gt;If a DNS forwarder is configured, the forwarder will 'see' all your DNS queries and will be able to build a nice profile about you as a person or organisation.&lt;/p&gt;
&lt;p&gt;It's up to you if you care about this 'risk'.&lt;/p&gt;
&lt;h2&gt;Running Pi-hole and BIND9 together&lt;/h2&gt;
&lt;h3&gt;Pi-hole only supports forwarders?&lt;/h3&gt;
&lt;p&gt;Because Pi-hole requires a DNS forwarder to be configured, I'm also running BIND as the actual DNS server that performs the outbound DNS queries.&lt;/p&gt;
&lt;p&gt;Both Pi-hole and BIND want to listen on UDP port 53, which won't work&lt;sup id="fnref:alternative"&gt;&lt;a class="footnote-ref" href="#fn:alternative"&gt;2&lt;/a&gt;&lt;/sup&gt;. In my case, I've configured BIND9 to listen on UDP port 5353 and configured Pi-hole to use '&lt;em&gt;BIND listen ip address&lt;/em&gt;#5353' as a forwarder.&lt;/p&gt;
&lt;p&gt;This setup means that I benefit from the ad blocking by Pi-hole and won't send all my DNS requests to Google.&lt;/p&gt;
&lt;h3&gt;Help, my local DNS authoritative '.internal' zone isn't working anymore!&lt;/h3&gt;
&lt;p&gt;I'm running a local DNS domain 'xyz.internal' for servers and services in my network. I've also configured my DHCP server to tell clients the search domain is 'xyz.internal', so when I issue &lt;code&gt;ssh server01&lt;/code&gt; this will automatically resolve to &lt;code&gt;server01.xyz.internal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So to summarise, my BIND DNS server is both the DNS server that respons to client DNS lookups via Pi-hole for public domains, and it's also authoritative for the 'xyz.internal' domain.&lt;/p&gt;
&lt;p&gt;However, there's a problem with this setup.&lt;/p&gt;
&lt;p&gt;Pi-hole does not forward queries for the '.internal' domain because it considers upstream forwarding DNS servers as potentially hostile. Forwarding queries for '.internal' domains would expose potentially sensitive information.&lt;/p&gt;
&lt;p&gt;This behaviour can be circumvented with the 'Conditional forwarding' option within Pi-hole. This allows DNS clients contacting the Pi-hole server to still query '.internal' domains. This is an example configuration line:&lt;/p&gt;
&lt;p&gt;true,10.10.10.0/24,10.10.10.1#5353,xyz.internal&lt;/p&gt;
&lt;p&gt;In this example, Pi-hole will forward DNS queries for the xyz.internal domain towards 10.10.10.1#5353 and everything will work as expected.&lt;/p&gt;
&lt;h2&gt;Q &amp;amp; A&lt;/h2&gt;
&lt;h3&gt;How does the DNS server know how to contact the .org root server?&lt;/h3&gt;
&lt;p&gt;The DNS server is accompanied by a 'root zone file' containing the IP addresses for the root servers. As these IP addresses are not static, they need to be updated periodically. In Debian Linux (for example), this file is automatically updated through APT with the 'dns-root-data' package.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:public"&gt;
&lt;p&gt;Probably an address from Google, Cloudflare or OpenDNS.&amp;#160;&lt;a class="footnote-backref" href="#fnref:public" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:alternative"&gt;
&lt;p&gt;It's possible to make Pi-hole and BIND listen on different interfaces, thus allowing both of them to use port 53 but that's another story and may not be that handy.&amp;#160;&lt;a class="footnote-backref" href="#fnref:alternative" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:cluster"&gt;
&lt;p&gt;A root server is not a single physical server but a group of physical servers, but I consider this an implementation detail.&amp;#160;&lt;a class="footnote-backref" href="#fnref:cluster" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Infrastructure"/></entry><entry><title>Sharing group_var variables across Ansible inventories</title><link href="https://louwrentius.com/sharing-group_var-variables-across-ansible-inventories.html" rel="alternate"/><published>2025-12-20T12:00:00+01:00</published><updated>2025-12-20T12:00:00+01:00</updated><author><name>Louwrentius</name></author><id>tag:louwrentius.com,2025-12-20:/sharing-group_var-variables-across-ansible-inventories.html</id><summary type="html">&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;Some time ago I worked with a customer that used Ansible to deploy a multitude of applications across their individual TAP&lt;sup id="fnref:dtap"&gt;&lt;a class="footnote-ref" href="#fn:dtap"&gt;1&lt;/a&gt;&lt;/sup&gt; environments.&lt;/p&gt;
&lt;p&gt;Unfortunately the Ansible inventory was setup in such a way that &lt;code&gt;group_vars&lt;/code&gt; variables for a specific application were manually duplicated across each TAP environment.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ansible Inventory Hierarchy" src="https://louwrentius.com/static/images/ansible-inventory/ansible_hierarchy.png" /&gt;
&lt;em&gt;Example …&lt;/em&gt;&lt;/p&gt;</summary><content type="html">&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;Some time ago I worked with a customer that used Ansible to deploy a multitude of applications across their individual TAP&lt;sup id="fnref:dtap"&gt;&lt;a class="footnote-ref" href="#fn:dtap"&gt;1&lt;/a&gt;&lt;/sup&gt; environments.&lt;/p&gt;
&lt;p&gt;Unfortunately the Ansible inventory was setup in such a way that &lt;code&gt;group_vars&lt;/code&gt; variables for a specific application were manually duplicated across each TAP environment.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ansible Inventory Hierarchy" src="https://louwrentius.com/static/images/ansible-inventory/ansible_hierarchy.png" /&gt;
&lt;em&gt;Example of inventory folder hierarchy&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Changing or adding a &lt;code&gt;group_vars&lt;/code&gt; variable meant updating the &lt;code&gt;group_vars&lt;/code&gt; file for each TAP environment. Making changes to &lt;code&gt;group_vars&lt;/code&gt; in this environment is a cognitive burden: there is a high risk that one of the environments is missed by mistake.&lt;/p&gt;
&lt;p&gt;The different TAP environments share the vast majority of all &lt;code&gt;group_var&lt;/code&gt; variables, except for just a few variables that are environment-specific. There should be no reason to duplicate &lt;code&gt;group_vars&lt;/code&gt; variables for each environment.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;h3&gt;A shared folder symlinked into group_vars&lt;/h3&gt;
&lt;p&gt;Within the application inventory folder, We first create a folder called &lt;em&gt;000_shared&lt;/em&gt; that will contain all &lt;code&gt;group_vars&lt;/code&gt; YAML files with variables that are shared across all TAP environments.&lt;/p&gt;
&lt;p&gt;Next, we symlink this folder within each &lt;code&gt;group_vars&lt;/code&gt; folder of each environment. Each environment also contains environment-specific configuration in one or more separate files.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ansible Inventory Hierarchy" src="https://louwrentius.com/static/images/ansible-inventory/ansible_symlink.png" /&gt;&lt;/p&gt;
&lt;p&gt;With this example, any change within &lt;code&gt;webserver.yaml&lt;/code&gt; will be applied to all TAP environments of the 'Alpha' application.&lt;/p&gt;
&lt;h3&gt;Sharing group_vars variables across applications&lt;/h3&gt;
&lt;p&gt;We can apply this trick one level higher: we can create a shared folder called &lt;em&gt;000_shared_global&lt;/em&gt; containing settings that are shared across all application environments.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ansible Inventory Hierarchy" src="https://louwrentius.com/static/images/ansible-inventory/ansible_global.png" /&gt;&lt;/p&gt;
&lt;p&gt;In this example, we could change the DNS configuration for all environments by changing the settings in one, single file. But the global shared &lt;code&gt;group_vars&lt;/code&gt; can be used to assure a (security) baseline between unrelated applications that do share similar technology (All Python or PHP applications).&lt;/p&gt;
&lt;h2&gt;Evaluation&lt;/h2&gt;
&lt;p&gt;Implementing this solution in an existing Ansible 'code base' can be a significant undertaking, but the long-term benefits seem worth it. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It reduces the amount of work required for changes&lt;/li&gt;
&lt;li&gt;It reduces the risk of human error&lt;/li&gt;
&lt;li&gt;It reduces the cognitive load &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The good news is that you can migrate to this new style of inventory at your own pace, there is no need for a big-bang deployment. Changes can be made to one environment at a time.&lt;/p&gt;
&lt;h2&gt;Q &amp;amp; A&lt;/h2&gt;
&lt;h3&gt;Why the leading 000 zeros in shared folder names?&lt;/h3&gt;
&lt;p&gt;Ansible parses &lt;code&gt;group_vars&lt;/code&gt; YAML files according to their order within a directory. This means that the shared folders should be named with leading zeros, to assure that they are always parsed first. &lt;/p&gt;
&lt;p&gt;This allows you to override shared &lt;code&gt;group_vars&lt;/code&gt; settings for a particular environment, because these environment-specific files will be parsed later and their variable settings will be applied. &lt;/p&gt;
&lt;h3&gt;Just use one inventory for DTAP!&lt;/h3&gt;
&lt;p&gt;You can create a single inventory for test, acceptance and production, and separate the environments with groups. A shared group contains shared settings and environment-specific settings are put in the group_vars of the specific group. Unfortunately there is a risk:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.ansible.com/projects/ansible/devel/inventory_guide/intro_inventory.html#inventory-basics-formats-hosts-and-groups"&gt;Ansible documentation:&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you need to manage multiple environments, consider defining only the hosts of a single environment in each inventory. This way, it is harder to, for example, accidentally change the state of nodes inside the “test” environment when you wanted to update some “staging” servers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Therefore, I would recommend against this approach.&lt;/p&gt;
&lt;h3&gt;Changes impact production?&lt;/h3&gt;
&lt;p&gt;Changing shared &lt;code&gt;group_vars&lt;/code&gt; variables means that all environments are changed, including production. This requires proper code review and deployment processes that assures that said changes are only deployed to production when test and acceptance environments have been changed first.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:dtap"&gt;
&lt;p&gt;Development, Test, Acceptance and Production&amp;#160;&lt;a class="footnote-backref" href="#fnref:dtap" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:blastradius"&gt;
&lt;p&gt;When an inventory contains test, acceptance and prod environments it's easy to target all three environments by mistake.&amp;#160;&lt;a class="footnote-backref" href="#fnref:blastradius" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="Infrastructure"/><category term="Ansible"/></entry></feed>