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
|
||||
|
||||
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
|
||||
|
||||
@ -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-core>=2.10
|
||||
ansible-builder
|
||||
dnspython
|
||||
hcloud>=1.16.0
|
||||
jmespath
|
||||
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