I need to automate AWS Route 53 operation with Ansible, and here is a note. (As Ansible always does, most useful informations are in the official document.)
According to the Ansible official document, We need to install boto
(AWS SDK for Python).
pip install -U boto
boto uses two keys in order to use AWS API under the hood. Here is a good guide how to get the keys. After obtaining the keys, we should export your Ansible execution environment.
There are several methods in an official document, and I use For environment variables
method.
export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'
According to the official document,
In your playbook steps we’ll typically be using the following pattern for provisioning steps:
- hosts: localhost gather_facts: False tasks: - ...
Intuitivly, all users use same target AWS API
because the target might be AWS API server in this case.
But, we should use localhost
at hosts
in your playbook.
Ansible official documents always give us a sample codes and they are so helpful always! So I don’t need to leave a memo actually, but for my reference, I leave it here.
# Retrieve the details and save it
- name: Check the status (1/2).
route53:
state: get
zone: myzone.com
record: front1.myzone.com
type: A
register: rec
# Show the data
- name: Check the status (2/2).
debug:
msg: "{{ rec }}"
- name: Add an A record
route53:
state: present
zone: myzone.com
record: front2.myzone.com
type: A
ttl: 3600
value: 1.2.3.4
- name: Retrieve the details for front2.myzone.com
route53:
state: get
zone: myzone.com
record: front2.myzone.com
type: A
register: rec
- name: Delete front2.myzone.com A record using the results from the get command
route53:
state: absent
zone: myzone.com
record: "{{ rec.set.record }}"
ttl: "{{ rec.set.ttl }}"
type: "{{ rec.set.type }}"
value: "{{ rec.set.value }}"
If you want to delete a record, you should specify not only a record name, but also values should be specified. We use, therefore `two step method, but you can delete in a tasks like below.
Delete an A record
- name: Delete an A record
route53:
state: absent
zone: myzone.com
record: front2.myzone.com
type: A
ttl: 3600
value: 1.2.3.4
wait: yes
As of April 2020, there is no “modify” parameter, so you can delete a value from multi A values record.
Instead, we should use overwrite
parameter.
As of April 2020, when an A record has multi-vaules, it return set.vaules
, but the vairable name values
is bad name…
As you mentioned that “{{ansible_local.hdfs.items}}” is printing built-in method items of dict object at 0x7f81f42b2c58.
This is happening because the name items is clashing with the name of some built-in method. So you just need to change the name to something else, you can not use items name in your hdfs.fact file.
{{ set.value }}
returns CSV textline of the IPs.
We can use it for multi-value A record.
I also used a script values_csv_to_list.sh
.
---
# Retrieve the details for
- name: Retrive the details about the A record of front1.myzone.com, which has multi-values in the record.
route53:
state: get
zone: myzone.com
record: front1.myzone.com
type: A
register: rec
- name: Check the IPs in the record.
debug:
msg: "{{ rec.set.value }}"
- name: Run a script (CSV -> list)
script:
cmd: values_csv_to_list.sh "{{ rec.set.value }}"
register: IPs
- name: Add an IP 1.2.3.4.
set_fact:
new_IPs_list: "{{ IPs.stdout_lines + ['1.2.3.4'] }}"
- name: Append all items in new_IP_list in commna seperated form.
debug:
msg: "{{ new_IPs_list | join(',')}}"
values_csv_to_list.sh
#!/bin/bash
IFS=","
for v in $@
do
echo $v
done
Using jinja2 syntac.
- name: Append all items in new_IP_list in commna seperated form.
debug:
msg: "{{ new_IP_list | join(',')}}"