148 lines
6.0 KiB
YAML
148 lines
6.0 KiB
YAML
---
|
|
- name: Update Cloudflare DNS for observability.svc.plus
|
|
hosts: localhost
|
|
connection: local
|
|
gather_facts: false
|
|
vars:
|
|
cloudflare_zone_name: svc.plus
|
|
cloudflare_api_base: https://api.cloudflare.com/client/v4
|
|
observability_domain: observability.svc.plus
|
|
observability_dns_target: us-xhttp.svc.plus
|
|
observability_dns_type: CNAME
|
|
observability_dns_ttl: 1
|
|
observability_dns_proxied: false
|
|
dns_wait_retries: 30
|
|
dns_wait_delay: 10
|
|
tasks:
|
|
- name: Validate Cloudflare token is present in environment
|
|
ansible.builtin.assert:
|
|
that:
|
|
- lookup('ansible.builtin.env', 'CLOUDFLARE_API_TOKEN') | length > 0
|
|
fail_msg: "CLOUDFLARE_API_TOKEN must be exported before running this playbook."
|
|
|
|
- name: Resolve Cloudflare zone id
|
|
ansible.builtin.uri:
|
|
url: "{{ cloudflare_api_base }}/zones?name={{ cloudflare_zone_name }}"
|
|
method: GET
|
|
headers:
|
|
Authorization: "Bearer {{ lookup('ansible.builtin.env', 'CLOUDFLARE_API_TOKEN') }}"
|
|
Content-Type: application/json
|
|
return_content: true
|
|
register: cloudflare_zone_lookup
|
|
|
|
- name: Validate zone lookup result
|
|
ansible.builtin.assert:
|
|
that:
|
|
- cloudflare_zone_lookup.json.success
|
|
- cloudflare_zone_lookup.json.result | length > 0
|
|
fail_msg: "Unable to resolve Cloudflare zone id for {{ cloudflare_zone_name }}."
|
|
|
|
- name: Set Cloudflare zone id
|
|
ansible.builtin.set_fact:
|
|
cloudflare_zone_id: "{{ cloudflare_zone_lookup.json.result[0].id }}"
|
|
|
|
- name: Query existing observability DNS records
|
|
ansible.builtin.uri:
|
|
url: "{{ cloudflare_api_base }}/zones/{{ cloudflare_zone_id }}/dns_records?name={{ observability_domain }}"
|
|
method: GET
|
|
headers:
|
|
Authorization: "Bearer {{ lookup('ansible.builtin.env', 'CLOUDFLARE_API_TOKEN') }}"
|
|
Content-Type: application/json
|
|
return_content: true
|
|
register: observability_dns_records
|
|
|
|
- name: Remove conflicting observability DNS records with different type
|
|
ansible.builtin.uri:
|
|
url: "{{ cloudflare_api_base }}/zones/{{ cloudflare_zone_id }}/dns_records/{{ item.id }}"
|
|
method: DELETE
|
|
headers:
|
|
Authorization: "Bearer {{ lookup('ansible.builtin.env', 'CLOUDFLARE_API_TOKEN') }}"
|
|
Content-Type: application/json
|
|
loop: "{{ observability_dns_records.json.result | default([]) }}"
|
|
loop_control:
|
|
label: "{{ item.type }} {{ item.name }}"
|
|
when: item.type != observability_dns_type
|
|
|
|
- name: Create observability DNS record when missing
|
|
ansible.builtin.uri:
|
|
url: "{{ cloudflare_api_base }}/zones/{{ cloudflare_zone_id }}/dns_records"
|
|
method: POST
|
|
headers:
|
|
Authorization: "Bearer {{ lookup('ansible.builtin.env', 'CLOUDFLARE_API_TOKEN') }}"
|
|
Content-Type: application/json
|
|
body_format: raw
|
|
body: >-
|
|
{{
|
|
{
|
|
'type': observability_dns_type,
|
|
'name': observability_domain,
|
|
'content': observability_dns_target,
|
|
'ttl': (observability_dns_ttl | int),
|
|
'proxied': (observability_dns_proxied | bool)
|
|
} | to_json
|
|
}}
|
|
when: (observability_dns_records.json.result | selectattr('type', 'equalto', observability_dns_type) | list | length) == 0
|
|
|
|
- name: Update observability DNS record when target changes
|
|
ansible.builtin.uri:
|
|
url: "{{ cloudflare_api_base }}/zones/{{ cloudflare_zone_id }}/dns_records/{{ (observability_dns_records.json.result | selectattr('type', 'equalto', observability_dns_type) | list | first).id }}"
|
|
method: PUT
|
|
headers:
|
|
Authorization: "Bearer {{ lookup('ansible.builtin.env', 'CLOUDFLARE_API_TOKEN') }}"
|
|
Content-Type: application/json
|
|
body_format: raw
|
|
body: >-
|
|
{{
|
|
{
|
|
'type': observability_dns_type,
|
|
'name': observability_domain,
|
|
'content': observability_dns_target,
|
|
'ttl': (observability_dns_ttl | int),
|
|
'proxied': (observability_dns_proxied | bool)
|
|
} | to_json
|
|
}}
|
|
when:
|
|
- (observability_dns_records.json.result | selectattr('type', 'equalto', observability_dns_type) | list | length) > 0
|
|
- >
|
|
((observability_dns_records.json.result | selectattr('type', 'equalto', observability_dns_type) | list | first).content != observability_dns_target)
|
|
or
|
|
(((observability_dns_records.json.result | selectattr('type', 'equalto', observability_dns_type) | list | first).proxied | default(false)) != observability_dns_proxied)
|
|
|
|
- name: Wait for public DNS to expose observability CNAME
|
|
ansible.builtin.uri:
|
|
url: "https://cloudflare-dns.com/dns-query?name={{ observability_domain }}&type=CNAME"
|
|
method: GET
|
|
headers:
|
|
Accept: application/dns-json
|
|
return_content: true
|
|
register: observability_dns_public
|
|
until:
|
|
- observability_dns_public.status == 200
|
|
- >
|
|
(
|
|
observability_dns_public.json.Status
|
|
if (observability_dns_public.json is defined)
|
|
else ((observability_dns_public.content | from_json).Status | default(1))
|
|
) == 0
|
|
- >
|
|
(
|
|
observability_dns_public.json.Answer
|
|
if (observability_dns_public.json is defined)
|
|
else ((observability_dns_public.content | from_json).Answer | default([]))
|
|
) | selectattr('data', 'equalto', observability_dns_target ~ '.')
|
|
| list | length > 0
|
|
retries: "{{ dns_wait_retries }}"
|
|
delay: "{{ dns_wait_delay }}"
|
|
|
|
- name: Show effective observability DNS target
|
|
ansible.builtin.debug:
|
|
msg: "{{ observability_domain }} -> {{ observability_dns_target }} proxied={{ observability_dns_proxied }}"
|
|
|
|
- import_playbook: infra.yml
|
|
vars:
|
|
infra_domain: observability.svc.plus
|
|
infra_portal:
|
|
home: { domain: observability.svc.plus }
|
|
caddy_enabled: true
|
|
nginx_enabled: false
|