Does anyone have a better solution for configuring instances with a hostname before that hostname can be assigned to the server?
Let's say we're using AWS and instantiate instance ec2-1-2-3-4.compute-1.amazonaws.com. When it's configured, we'll eventually assign it a CNAME in DNS of new-instance.example.com to replace an existing instance already in production.
new-instance.example.com already exists and is in production, so we can't reassign the CNAME to ec2-1-2-3-4.compute-1.amazonaws.com until the machine is configured properly and we're ready to switch over. We want internal configuration files and the hostname on the instance to be new-instance.example.com now, however, in preparation for the DNS change. So we can't use the inventory_hostname variable because it will be ec2-1-2-3-4.compute-1.amazonaws.com. I also have normal production servers that don't need to use a new hostname, so I'd like to be able to use the existing inventory_hostname with them.
My best idea so far has been to assign a variable in the inventory file:
[production]
ec2-1-2-3-4.compute-1.amazonaws.com new_hostname=new-instance.example.com
In the playbook, I can test for the existence of new_hostname. If new_hostname exists, it's used and if it doesn't, inventory_hostname is used. This will cause a fatal error unless error_on_undefined_vars is set to false and I'd prefer not to set this for the benefit it provides of preventing typos. An example of failure below.
Test Playbook:
- hosts: all
tasks:
- name: "Debug hostname"
debug: msg="inventory_hostname={{ inventory_hostname }}, hostvars[inventory_hostname]['inventory_hostname']={{ hostvars[inventory_hostname]['inventory_hostname'] }}, ansible_hostname={{ ansible_hostname }}, new_hostname={{ new_hostname }}"
ignore_errors: yes
Results:
TASK: [Debug hostname] ********************************************************
fatal: [ec2-1-2-3-4.compute-1.amazonaws.com] => One or more undefined variables: 'new_hostname' is undefined
Setting new_hostname for every single server would work, but I don't want to set it for every one, just the ones that need the new hostname. It also breaks hostname grouping like:
ec2-1-2-3-[4:5].compute-1.amazonaws.com
If new_hostname exists, this works:
- name: "set hostname fact"
set_fact: testvar1={{ new_hostname }} || {{ inventory_hostname }}
- name: "show hostname fact"
debug: msg="testvar1={{ testvar1 }}"
Results:
TASK: [set hostname fact] *****************************************************
ok: [ec2-1-2-3-4.compute-1.amazonaws.com]
TASK: [show hostname fact] ****************************************************
ok: [ec2-1-2-3-4.compute-1.amazonaws.com] => {"msg": "testvar1=new-instance.example.com"}
If error_on_undefined_vars is set to the default of true, however, and new_hostname is not set, it fails.
Best practices on this strategy?
Being very shy on this because I am also new to ansible and if I understand your problem, one way is to use when: something is defined
on the task.
Example:
tasks:
- name: "Debug hostname"
debug: msg="inventory_hostname={{ inventory_hostname }}, hostvars[inventory_hostname]['inventory_hostname']={{ hostvars[inventory_hostname]['inventory_hostname'] }}, ansible_hostname={{ ansible_hostname }}, new_hostname={{ new_hostname }}"
when: new_hostname is defined
Now that's one approach. Another would be to make a role for that and only play that role (the spinning up procedure) separately to a target machine from an added entry in the inventory maybe. Take a look at the best practices if you like as well for some extra reading.
When standing up cloud-init to set the hostname. (I use Chef but that isn't relevant to the solution here). This gets around the problem of setting the hostname in your automation framework as it's already set by the time the node boots.
Part of my cloud config sets the fqdn
and manage_etc_hosts
options like so:
fqdn: new-instance.example.com
manage_etc_hosts: true
There are plenty of example configuration fragments in the doc/examples directory and it's easy to play around and find a setup that you like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With