observability.svc.plus/deploy_observability_service.yml

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