DEV-253: digitalocean stuff - add droplet but not idempotentgit branch git branch plz check
parent
54d6b82f1f
commit
5bdff07d1b
@ -1,4 +1,6 @@
|
|||||||
# Execution Environment for AWX
|
# Execution Environment for AWX
|
||||||
|
|
||||||
ansible-builder build --tag dev-docker-registry-01.smardigo.digital/awx/awx-custom-ee:latest
|
ansible-builder build --tag dev-docker-registry-01.smardigo.digital/awx/awx-custom-ee:latest
|
||||||
|
docker login dev-docker-registry-01.smardigo.digital
|
||||||
|
docker tag XXXXXXXX dev-docker-registry-01.smardigo.digital/awx/awx-custom-ee:latest
|
||||||
docker push dev-docker-registry-01.smardigo.digital/awx/awx-custom-ee
|
docker push dev-docker-registry-01.smardigo.digital/awx/awx-custom-ee
|
||||||
|
|||||||
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
- name: 'apply setup to {{ host | default("all") }}'
|
||||||
|
hosts: '{{ host | default("all") }}'
|
||||||
|
serial: "{{ serial_number | default(5) }}"
|
||||||
|
tasks:
|
||||||
|
- set_fact:
|
||||||
|
dev_prometheus_fqdn: 'dev-prometheus-01.{{ domain }}'
|
||||||
|
qa_prometheus_fqdn: 'qa-prometheus-01.{{ domain }}'
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
dev_prometheus_ip: "{{ lookup('community.general.dig', dev_prometheus_fqdn ) }}"
|
||||||
|
qa_prometheus_ip: "{{ lookup('community.general.dig', qa_prometheus_fqdn ) }}"
|
||||||
|
|
||||||
|
- name: "Allow SSH in UFW"
|
||||||
|
ufw:
|
||||||
|
rule: limit
|
||||||
|
port: 22
|
||||||
|
proto: tcp
|
||||||
|
|
||||||
|
- name: "Allow port 9100 for node-exporter in UFW"
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: 9100
|
||||||
|
proto: tcp
|
||||||
|
src: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- "{{ dev_prometheus_ip }}"
|
||||||
|
- "{{ qa_prometheus_ip }}"
|
||||||
|
|
||||||
|
- name: "Allow port 9115 for blackbox-exporter in UFW"
|
||||||
|
ufw:
|
||||||
|
rule: allow
|
||||||
|
port: 9115
|
||||||
|
proto: tcp
|
||||||
|
src: "{{ item }}"
|
||||||
|
loop:
|
||||||
|
- "{{ dev_prometheus_ip }}"
|
||||||
|
- "{{ qa_prometheus_ip }}"
|
||||||
|
|
||||||
|
- name: "Set firewall default policy"
|
||||||
|
ufw:
|
||||||
|
state: enabled
|
||||||
|
policy: reject
|
||||||
|
|
||||||
|
- name: "configure ssh_hardening"
|
||||||
|
include_role:
|
||||||
|
# include role from collection called 'devsec'
|
||||||
|
name: devsec.hardening.ssh_hardening
|
||||||
|
apply:
|
||||||
|
tags:
|
||||||
|
- ssh_hardening
|
||||||
|
tags:
|
||||||
|
- ssh_hardening
|
||||||
|
|
||||||
|
- name: "Install node-exporter via include_role"
|
||||||
|
include_role:
|
||||||
|
name: cloudalchemy.node-exporter
|
||||||
|
|
||||||
|
- name: "Install blackbox-exporter via include_role"
|
||||||
|
include_role:
|
||||||
|
name: cloudalchemy.blackbox-exporter
|
||||||
|
apply:
|
||||||
|
tags:
|
||||||
|
- blackbox
|
||||||
|
tags:
|
||||||
|
- blackbox
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
ansible_ssh_host: "{{ inventory_hostname }}.{{ domain }}"
|
||||||
|
|
||||||
|
droplet_defaults:
|
||||||
|
size: s-1vcpu-1gb
|
||||||
|
region: fra1
|
||||||
|
image: ubuntu-20-04-x64
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
blackbox_exporter_cli_flags:
|
||||||
|
log.level: warn
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
vars:
|
||||||
|
hcloud_firewall_objects:
|
||||||
|
-
|
||||||
|
name: monitoring-extern-https
|
||||||
|
state: present
|
||||||
|
rules:
|
||||||
|
-
|
||||||
|
direction: in
|
||||||
|
protocol: tcp
|
||||||
|
port: '443'
|
||||||
|
source_ips:
|
||||||
|
- "{{ lookup('community.general.dig', 'dev-blackbox-01.smardigo.digital' ) }}/32"
|
||||||
|
destination_ips: []
|
||||||
|
description: null
|
||||||
|
apply_to:
|
||||||
|
-
|
||||||
|
type: label_selector
|
||||||
|
label_selector:
|
||||||
|
selector: 'service=connect'
|
||||||
|
-
|
||||||
|
type: label_selector
|
||||||
|
label_selector:
|
||||||
|
selector: 'service=keycloak'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: "Setup hcloud firewall via include_role"
|
||||||
|
include_role:
|
||||||
|
name: hcloud
|
||||||
|
tasks_from: configure-firewall2
|
||||||
|
loop: "{{ hcloud_firewall_objects }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: firewall_object
|
||||||
@ -1,5 +1,7 @@
|
|||||||
ansible
|
ansible
|
||||||
ansible-core>=2.10
|
ansible-core>=2.10
|
||||||
|
ansible-builder
|
||||||
|
dnspython
|
||||||
hcloud>=1.16.0
|
hcloud>=1.16.0
|
||||||
jmespath
|
jmespath
|
||||||
netaddr
|
netaddr
|
||||||
|
|||||||
@ -0,0 +1,69 @@
|
|||||||
|
- name: "Create ssh key"
|
||||||
|
delegate_to: localhost
|
||||||
|
community.digitalocean.digital_ocean_sshkey:
|
||||||
|
oauth_token: "{{ digitalocean_authentication_token }}"
|
||||||
|
name: "{{ item }}"
|
||||||
|
ssh_pub_key: "{{ lookup('file', 'users/' + item + '/ssh.pub') }}"
|
||||||
|
state: present
|
||||||
|
register: result
|
||||||
|
loop: '{{ smardigo_plattform_users }}'
|
||||||
|
|
||||||
|
- name: "Get fingerprints for ssh_keys"
|
||||||
|
delegate_to: localhost
|
||||||
|
community.digitalocean.digital_ocean_sshkey_info:
|
||||||
|
oauth_token: "{{ digitalocean_authentication_token }}"
|
||||||
|
register: do_sshkeys_found
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
droplet_combined: "{{ droplet_defaults | combine(droplet) }}"
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- set_fact:
|
||||||
|
tag_service: "{{ droplet.name | regex_search('[a-z]+-([a-z]+)-[0-9]+','\\1') | first | string }}"
|
||||||
|
tag_stage: "{{ droplet.name | regex_search('([a-z]+)-[a-z]+-[0-9]+','\\1') | first | string }}"
|
||||||
|
|
||||||
|
- name: "Create new droplet"
|
||||||
|
delegate_to: localhost
|
||||||
|
community.digitalocean.digital_ocean_droplet:
|
||||||
|
oauth_token: "{{ digitalocean_authentication_token }}"
|
||||||
|
state: "{{ droplet_combined.state | default('present') }}"
|
||||||
|
name: "{{ droplet_combined.name }}"
|
||||||
|
size: "{{ droplet_combined.size }}"
|
||||||
|
region: "{{ droplet_combined.region }}"
|
||||||
|
image: "{{ droplet_combined.image }}"
|
||||||
|
wait_timeout: "{{ droplet_combined.wait_timeout | default(500) }}"
|
||||||
|
unique_name: "{{ droplet_combined.unique_name | default(True) }}"
|
||||||
|
ssh_keys: "{{ do_sshkeys_found.data | json_query(querystring) }}"
|
||||||
|
register: new_droplet
|
||||||
|
vars:
|
||||||
|
querystring: "[*].fingerprint"
|
||||||
|
|
||||||
|
- name: "Tag new server"
|
||||||
|
delegate_to: localhost
|
||||||
|
community.digitalocean.digital_ocean_tag:
|
||||||
|
oauth_token: "{{ digitalocean_authentication_token }}"
|
||||||
|
name: "{{ item | replace('-','_') }}"
|
||||||
|
resource_id: "{{ new_droplet.data.droplet.id }}"
|
||||||
|
state: present
|
||||||
|
register: tag_response
|
||||||
|
loop: "{{ droplet.tags }}"
|
||||||
|
|
||||||
|
- name: "Set fact"
|
||||||
|
delegate_to: localhost
|
||||||
|
set_fact:
|
||||||
|
stage_server_ip: "{{ item }}"
|
||||||
|
loop: "{{ new_droplet.data | community.general.json_query(jsonquery_ipaddress) }}"
|
||||||
|
vars:
|
||||||
|
jsonquery_ipaddress: "droplet.networks.v4[?type=='public'].ip_address"
|
||||||
|
|
||||||
|
# TODO: abolish _digitalocean/tasks/domain.yml
|
||||||
|
- name: "Create dns record for droplet"
|
||||||
|
delegate_to: localhost
|
||||||
|
community.digitalocean.digital_ocean_domain_record:
|
||||||
|
oauth_token: "{{ digitalocean_authentication_token }}"
|
||||||
|
state: present
|
||||||
|
domain: "{{ domain }}"
|
||||||
|
type: A
|
||||||
|
name: "{{ new_droplet.data.droplet.name }}"
|
||||||
|
data: "{{ stage_server_ip }}"
|
||||||
|
force_update: yes
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
---
|
||||||
|
- name: "Get all existing firewalls"
|
||||||
|
uri:
|
||||||
|
method: GET
|
||||||
|
url: "https://api.hetzner.cloud/v1/firewalls"
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
accept: application/json
|
||||||
|
authorization: Bearer {{ hetzner_authentication_token }}
|
||||||
|
status_code: [200]
|
||||||
|
register: hcloud_firewalls_all
|
||||||
|
delegate_to: 127.0.0.1
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: "Setting hetzner firewall pagination count: <{{ hcloud_firewalls_all.json.meta.pagination.last_page }}>"
|
||||||
|
set_fact:
|
||||||
|
total_server_pages: "{{ hcloud_firewalls_all.json.meta.pagination.last_page }}"
|
||||||
|
become: false
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
|
|
||||||
|
- name: "BLOCK << WITHOUT >> pagination"
|
||||||
|
block:
|
||||||
|
- set_fact:
|
||||||
|
lookup_fw_obj: "{{ hcloud_firewalls_all.json.firewalls | community.general.json_query(jsonquery_find_firewall_name) }}"
|
||||||
|
vars:
|
||||||
|
jsonquery_find_firewall_name: "[?name=='{{ firewall_object.name }}']"
|
||||||
|
when:
|
||||||
|
- total_server_pages == '1'
|
||||||
|
|
||||||
|
|
||||||
|
- name: "<< WITH >> pagination"
|
||||||
|
block:
|
||||||
|
- name: "Get all existing firewalls"
|
||||||
|
uri:
|
||||||
|
method: GET
|
||||||
|
url: "https://api.hetzner.cloud/v1/firewalls?page={{ item }}"
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
accept: application/json
|
||||||
|
authorization: Bearer {{ hetzner_authentication_token }}
|
||||||
|
status_code: [200]
|
||||||
|
register: hcloud_firewalls_all
|
||||||
|
delegate_to: 127.0.0.1
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
lookup_fw_obj: "{{ hcloud_firewalls_all.json.results | community.general.json_query(querystr1) | first | community.general.json_query(querystr2) | community.general.json_query(querystr2) }}"
|
||||||
|
vars:
|
||||||
|
querystr1: "[[*].json.firewalls]"
|
||||||
|
querystr2: "[?name=='{{ firewall_object.name }}']"
|
||||||
|
when:
|
||||||
|
- total_server_pages != '1'
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Create firewall rule for <<{{ firewall_object.name }}>>"
|
||||||
|
uri:
|
||||||
|
method: POST
|
||||||
|
url: "https://api.hetzner.cloud/v1/firewalls"
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
Content-Type: application/json
|
||||||
|
authorization: Bearer {{ hetzner_authentication_token }}
|
||||||
|
body: "{{ firewall_object | to_json }}"
|
||||||
|
return_content: yes
|
||||||
|
status_code: [201]
|
||||||
|
delegate_to: 127.0.0.1
|
||||||
|
become: false
|
||||||
|
when:
|
||||||
|
- firewall_object.state == 'present'
|
||||||
|
- lookup_fw_obj | length == 0
|
||||||
|
|
||||||
|
- name: "Update firewall rule for <<{{ firewall_object.name }}>>"
|
||||||
|
uri:
|
||||||
|
method: PUT
|
||||||
|
url: "https://api.hetzner.cloud/v1/firewalls/{{ lookup_fw_obj.0.id }}"
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
Content-Type: application/json
|
||||||
|
authorization: Bearer {{ hetzner_authentication_token }}
|
||||||
|
body: "{{ firewall_object | to_json }}"
|
||||||
|
return_content: yes
|
||||||
|
status_code: [200]
|
||||||
|
delegate_to: 127.0.0.1
|
||||||
|
become: false
|
||||||
|
when:
|
||||||
|
- firewall_object.state == 'present'
|
||||||
|
- lookup_fw_obj | length > 0
|
||||||
|
|
||||||
|
- name: "Delete firewall rule for <<{{ firewall_object.name }}>>"
|
||||||
|
block:
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
deactivate_fw_obj:
|
||||||
|
remove_from: "{{ firewall_object.apply_to }}"
|
||||||
|
|
||||||
|
- name: "Step_1: Unset usage of firewall rule <<{{ firewall_object.name }}>>"
|
||||||
|
uri:
|
||||||
|
method: POST
|
||||||
|
url: "https://api.hetzner.cloud/v1/firewalls/{{ lookup_fw_obj.0.id }}/actions/remove_from_resources"
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
Content-Type: application/json
|
||||||
|
authorization: Bearer {{ hetzner_authentication_token }}
|
||||||
|
body: "{{ deactivate_fw_obj | to_json }}"
|
||||||
|
return_content: yes
|
||||||
|
status_code: [201]
|
||||||
|
delegate_to: 127.0.0.1
|
||||||
|
become: false
|
||||||
|
|
||||||
|
- name: "Step_2: Delete firewall rule for <<{{ firewall_object.name }}>>"
|
||||||
|
uri:
|
||||||
|
method: DELETE
|
||||||
|
url: "https://api.hetzner.cloud/v1/firewalls/{{ lookup_fw_obj.0.id }}"
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
Content-Type: application/json
|
||||||
|
authorization: Bearer {{ hetzner_authentication_token }}
|
||||||
|
return_content: yes
|
||||||
|
status_code: [204]
|
||||||
|
register: cleanup_firewall
|
||||||
|
delegate_to: 127.0.0.1
|
||||||
|
become: false
|
||||||
|
until: cleanup_firewall.status in [204]
|
||||||
|
retries: 15
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
when:
|
||||||
|
- firewall_object.state == 'absent'
|
||||||
|
- lookup_fw_obj | length > 0
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
[blackbox]
|
||||||
|
dev-blackbox-01
|
||||||
|
|
||||||
|
[stage_dev:children]
|
||||||
|
blackbox
|
||||||
|
|
||||||
|
[all:children]
|
||||||
|
stage_dev
|
||||||
|
|
||||||
|
[digitalocean:children]
|
||||||
|
stage_dev
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue