chore: fix ansible-lint 6.17.2

This commit is contained in:
juju4 2023-08-26 15:12:49 +00:00
parent abb8164054
commit 0fa40513cd
52 changed files with 396 additions and 316 deletions

View file

@ -1,10 +1,15 @@
---
skip_list: skip_list:
- yaml - package-latest
- '204' - jinja[spacing]
verbosity: 1 verbosity: 1
warn_list: warn_list:
- no-changed-when - experimental
- no-handler - var-naming[pattern]
- fqcn-builtins - yaml[line-length]
- var-spacing # - no-changed-when
# - var-spacing
exclude_paths:
- .github/workflows/
- roles/cloud-*/files/stack.yaml

View file

@ -25,8 +25,9 @@ jobs:
- name: Checks and linters - name: Checks and linters
run: | run: |
/snap/bin/shellcheck algo install.sh /snap/bin/shellcheck algo install.sh
[ -f requirements.yml ] && ansible-galaxy install -r requirements.yml
ansible-playbook main.yml --syntax-check ansible-playbook main.yml --syntax-check
ansible-lint -x experimental,package-latest,unnamed-task -v *.yml roles/{local,cloud-*}/*/*.yml || true ansible-lint *.yml roles/{local,cloud-*}/*/*.yml || true
scripted-deploy: scripted-deploy:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04

View file

@ -7,6 +7,7 @@ timeout = 60
stdout_callback = default stdout_callback = default
display_skipped_hosts = no display_skipped_hosts = no
force_valid_group_names = ignore force_valid_group_names = ignore
callbacks_enabled = profile_tasks, timer
[paramiko_connection] [paramiko_connection]
record_host_keys = False record_host_keys = False

View file

@ -7,15 +7,16 @@
- config.cfg - config.cfg
tasks: tasks:
- block: - name: Play cloud
block:
- name: Local pre-tasks - name: Local pre-tasks
import_tasks: playbooks/cloud-pre.yml ansible.builtin.import_tasks: tasks/cloud-pre.yml
- name: Include a provisioning role - name: Include a provisioning role
include_role: ansible.builtin.include_role:
name: "{{ 'local' if algo_provider == 'local' else 'cloud-' + algo_provider }}" name: "{{ 'local' if algo_provider == 'local' else 'cloud-' + algo_provider }}"
- name: Local post-tasks - name: Local post-tasks
import_tasks: playbooks/cloud-post.yml ansible.builtin.import_tasks: tasks/cloud-post.yml
rescue: rescue:
- include_tasks: playbooks/rescue.yml - ansible.builtin.include_tasks: tasks/rescue.yml

View file

@ -27,9 +27,10 @@
- config.cfg - config.cfg
tasks: tasks:
- block: - name: Inputs
block:
- name: Cloud prompt - name: Cloud prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
What provider would you like to use? What provider would you like to use?
{% for p in providers_map %} {% for p in providers_map %}
@ -41,11 +42,11 @@
when: provider is undefined when: provider is undefined
- name: Set facts based on the input - name: Set facts based on the input
set_fact: ansible.builtin.set_fact:
algo_provider: "{{ provider | default(providers_map[_algo_provider.user_input|default(omit)|int - 1]['alias']) }}" algo_provider: "{{ provider | default(providers_map[_algo_provider.user_input|default(omit)|int - 1]['alias']) }}"
- name: VPN server name prompt - name: VPN server name prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Name the vpn server Name the vpn server
[algo] [algo]
@ -55,7 +56,7 @@
- algo_provider != "local" - algo_provider != "local"
- name: Cellular On Demand prompt - name: Cellular On Demand prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Do you want macOS/iOS clients to enable "Connect On Demand" when connected to cellular networks? Do you want macOS/iOS clients to enable "Connect On Demand" when connected to cellular networks?
[y/N] [y/N]
@ -63,7 +64,7 @@
when: ondemand_cellular is undefined when: ondemand_cellular is undefined
- name: Wi-Fi On Demand prompt - name: Wi-Fi On Demand prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Do you want macOS/iOS clients to enable "Connect On Demand" when connected to Wi-Fi? Do you want macOS/iOS clients to enable "Connect On Demand" when connected to Wi-Fi?
[y/N] [y/N]
@ -71,7 +72,7 @@
when: ondemand_wifi is undefined when: ondemand_wifi is undefined
- name: Trusted Wi-Fi networks prompt - name: Trusted Wi-Fi networks prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
List the names of any trusted Wi-Fi networks where macOS/iOS clients should not use "Connect On Demand" List the names of any trusted Wi-Fi networks where macOS/iOS clients should not use "Connect On Demand"
(e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi) (e.g., your home network. Comma-separated value, e.g., HomeNet,OfficeWifi,AlgoWiFi)
@ -81,7 +82,7 @@
- (ondemand_wifi|default(false)|bool) or (booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false)) - (ondemand_wifi|default(false)|bool) or (booleans_map[_ondemand_wifi.user_input|default(omit)]|default(false))
- name: Retain the PKI prompt - name: Retain the PKI prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Do you want to retain the keys (PKI)? (required to add users in the future, but less secure) Do you want to retain the keys (PKI)? (required to add users in the future, but less secure)
[y/N] [y/N]
@ -91,7 +92,7 @@
- ipsec_enabled - ipsec_enabled
- name: DNS adblocking prompt - name: DNS adblocking prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Do you want to enable DNS ad blocking on this VPN server? Do you want to enable DNS ad blocking on this VPN server?
[y/N] [y/N]
@ -99,7 +100,7 @@
when: dns_adblocking is undefined when: dns_adblocking is undefined
- name: SSH tunneling prompt - name: SSH tunneling prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Do you want each user to have their own account for SSH tunneling? Do you want each user to have their own account for SSH tunneling?
[y/N] [y/N]
@ -107,7 +108,7 @@
when: ssh_tunneling is undefined when: ssh_tunneling is undefined
- name: Set facts based on the input - name: Set facts based on the input
set_fact: ansible.builtin.set_fact:
algo_server_name: >- algo_server_name: >-
{% if server_name is defined %}{% set _server = server_name %} {% if server_name is defined %}{% set _server = server_name %}
{%- elif _algo_server_name.user_input is defined and _algo_server_name.user_input|length > 0 -%} {%- elif _algo_server_name.user_input is defined and _algo_server_name.user_input|length > 0 -%}
@ -140,4 +141,4 @@
{%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }} {%- elif _store_pki.user_input is defined %}{{ booleans_map[_store_pki.user_input] | default(defaults['store_pki']) }}
{%- else %}false{% endif %}{% endif %} {%- else %}false{% endif %}{% endif %}
rescue: rescue:
- include_tasks: playbooks/rescue.yml - ansible.builtin.include_tasks: playbooks/rescue.yml

View file

@ -3,26 +3,27 @@
become: false become: false
tasks: tasks:
- name: Playbook dir stat - name: Playbook dir stat
stat: ansible.builtin.stat:
path: "{{ playbook_dir }}" path: "{{ playbook_dir }}"
register: _playbook_dir register: _playbook_dir
- name: Ensure Ansible is not being run in a world writable directory - name: Ensure Ansible is not being run in a world writable directory
assert: ansible.builtin.assert:
that: _playbook_dir.stat.mode|int <= 775 that: _playbook_dir.stat.mode|int <= 775
msg: > msg: >
Ansible is being run in a world writable directory ({{ playbook_dir }}), ignoring it as an ansible.cfg source. Ansible is being run in a world writable directory ({{ playbook_dir }}), ignoring it as an ansible.cfg source.
For more information see https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir For more information see https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir
- name: Ensure the requirements installed - name: Ensure the requirements installed
debug: ansible.builtin.debug:
msg: "{{ '' | ipaddr }}" msg: "{{ '' | ipaddr }}"
ignore_errors: true ignore_errors: true
no_log: true no_log: true
register: ipaddr register: ipaddr
# FIXME! failing if another matching pattern in requirements.txt aka ansible-lint
- name: Set required ansible version as a fact - name: Set required ansible version as a fact
set_fact: ansible.builtin.set_fact:
required_ansible_version: "{{ item | regex_replace('^ansible[\\s+]?(?P<op>[=,>,<]+)[\\s+]?(?P<ver>\\d.\\d+(.\\d+)?)$', '{\"op\": \"\\g<op>\",\"ver\"\ required_ansible_version: "{{ item | regex_replace('^ansible[\\s+]?(?P<op>[=,>,<]+)[\\s+]?(?P<ver>\\d.\\d+(.\\d+)?)$', '{\"op\": \"\\g<op>\",\"ver\"\
: \"\\g<ver>\" }') }}" : \"\\g<ver>\" }') }}"
when: '"ansible" in item' when: '"ansible" in item'
@ -33,7 +34,7 @@
register: pip_package_info register: pip_package_info
- name: Verify Python meets Algo VPN requirements - name: Verify Python meets Algo VPN requirements
assert: ansible.builtin.assert:
that: (ansible_python.version.major|string + '.' + ansible_python.version.minor|string) is version('3.8', '>=') that: (ansible_python.version.major|string + '.' + ansible_python.version.minor|string) is version('3.8', '>=')
msg: > msg: >
Python version is not supported. Python version is not supported.
@ -41,7 +42,7 @@
See for more details - https://trailofbits.github.io/algo/troubleshooting.html#python-version-is-not-supported See for more details - https://trailofbits.github.io/algo/troubleshooting.html#python-version-is-not-supported
- name: Verify Ansible meets Algo VPN requirements - name: Verify Ansible meets Algo VPN requirements
assert: ansible.builtin.assert:
that: that:
- pip_package_info.packages.pip.ansible.0.version is version(required_ansible_version.ver, required_ansible_version.op) - pip_package_info.packages.pip.ansible.0.version is version(required_ansible_version.ver, required_ansible_version.op)
- not ipaddr.failed - not ipaddr.failed

View file

@ -1,6 +0,0 @@
---
- debug:
var: fail_hint
- name: Fail the installation
fail:

View file

@ -1,3 +1,3 @@
ansible==6.1.0 ansible==8.3.0
jinja2~=3.0.3 jinja2~=3.0.3
netaddr netaddr

12
requirements.yml Normal file
View file

@ -0,0 +1,12 @@
---
collections:
- community.general
- community.aws
- community.digitalocean
- amazon.aws
- azure.azcollection
- google.cloud
- hetzner.hcloud
- ngine_io.cloudstack
- vultr.cloud

View file

@ -1,18 +1,19 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- set_fact: - name: Set fact
ansible.builtin.set_fact:
algo_region: >- algo_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ azure_regions[_algo_region.user_input | int -1 ]['name'] }} {%- elif _algo_region.user_input %}{{ azure_regions[_algo_region.user_input | int -1 ]['name'] }}
{%- else %}{{ azure_regions[default_region | int - 1]['name'] }}{% endif %} {%- else %}{{ azure_regions[default_region | int - 1]['name'] }}{% endif %}
- name: Create AlgoVPN Server - name: Create AlgoVPN Server
azure_rm_deployment: azure.azcollection.azure_rm_deployment:
state: present state: present
deployment_name: "{{ algo_server_name }}" deployment_name: "{{ algo_server_name }}"
template: "{{ lookup('file', role_path + '/files/deployment.json') }}" template: "{{ lookup('file', role_path + '/files/deployment.json') }}"
@ -45,7 +46,8 @@
value: "{{ lookup('template', 'files/cloud-init/base.yml') | b64encode }}" value: "{{ lookup('template', 'files/cloud-init/base.yml') | b64encode }}"
register: azure_rm_deployment register: azure_rm_deployment
- set_fact: - name: Set fact
ansible.builtin.set_fact:
cloud_instance_ip: "{{ azure_rm_deployment.deployment.outputs.publicIPAddresses.value }}" cloud_instance_ip: "{{ azure_rm_deployment.deployment.outputs.publicIPAddresses.value }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,19 +1,23 @@
--- ---
- set_fact: - name: Set facts
ansible.builtin.set_fact:
secret: "{{ azure_secret | default(lookup('env','AZURE_SECRET'), true) }}" secret: "{{ azure_secret | default(lookup('env','AZURE_SECRET'), true) }}"
tenant: "{{ azure_tenant | default(lookup('env','AZURE_TENANT'), true) }}" tenant: "{{ azure_tenant | default(lookup('env','AZURE_TENANT'), true) }}"
client_id: "{{ azure_client_id | default(lookup('env','AZURE_CLIENT_ID'), true) }}" client_id: "{{ azure_client_id | default(lookup('env','AZURE_CLIENT_ID'), true) }}"
subscription_id: "{{ azure_subscription_id | default(lookup('env','AZURE_SUBSCRIPTION_ID'), true) }}" subscription_id: "{{ azure_subscription_id | default(lookup('env','AZURE_SUBSCRIPTION_ID'), true) }}"
- block: - name: Prompts
when: region is undefined
block:
- name: Set the default region - name: Set the default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in azure_regions %} {% for r in azure_regions %}
{%- if r['name'] == "eastus" %}{{ loop.index }}{% endif %} {%- if r['name'] == "eastus" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
{% for r in azure_regions %} {% for r in azure_regions %}
@ -23,4 +27,3 @@
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _algo_region register: _algo_region
when: region is undefined

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
requirements: https://raw.githubusercontent.com/ansible-collections/azure/v1.13.0/requirements-azure.txt requirements: https://raw.githubusercontent.com/ansible-collections/azure/v1.13.0/requirements-azure.txt
state: latest state: latest
virtualenv_python: python3 virtualenv_python: python3

View file

@ -1,25 +1,31 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- block: - name: Cloudstack
- set_fact: environment:
CLOUDSTACK_KEY: "{{ algo_cs_key }}"
CLOUDSTACK_SECRET: "{{ algo_cs_token }}"
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
block:
- name: Set facts
ansible.builtin.set_fact:
algo_region: >- algo_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input is defined and _algo_region.user_input | length > 0 %}{{ cs_zones[_algo_region.user_input | int -1 ]['name'] }} {%- elif _algo_region.user_input is defined and _algo_region.user_input | length > 0 %}{{ cs_zones[_algo_region.user_input | int -1 ]['name'] }}
{%- else %}{{ cs_zones[default_zone | int - 1]['name'] }}{% endif %} {%- else %}{{ cs_zones[default_zone | int - 1]['name'] }}{% endif %}
- name: Security group created - name: Security group created
cs_securitygroup: ngine_io.cloudstack.cs_securitygroup:
name: "{{ algo_server_name }}-security_group" name: "{{ algo_server_name }}-security_group"
description: AlgoVPN security group description: AlgoVPN security group
register: cs_security_group register: cs_security_group
- name: Security rules created - name: Security rules created
cs_securitygroup_rule: ngine_io.cloudstack.cs_securitygroup_rule:
security_group: "{{ cs_security_group.name }}" security_group: "{{ cs_security_group.name }}"
protocol: "{{ item.proto }}" protocol: "{{ item.proto }}"
start_port: "{{ item.start_port }}" start_port: "{{ item.start_port }}"
@ -32,13 +38,13 @@
- { proto: udp, start_port: "{{ wireguard_port }}", end_port: "{{ wireguard_port }}", range: 0.0.0.0/0 } - { proto: udp, start_port: "{{ wireguard_port }}", end_port: "{{ wireguard_port }}", range: 0.0.0.0/0 }
- name: Set facts - name: Set facts
set_fact: ansible.builtin.set_fact:
image_id: "{{ cloud_providers.cloudstack.image }}" image_id: "{{ cloud_providers.cloudstack.image }}"
size: "{{ cloud_providers.cloudstack.size }}" size: "{{ cloud_providers.cloudstack.size }}"
disk: "{{ cloud_providers.cloudstack.disk }}" disk: "{{ cloud_providers.cloudstack.disk }}"
- name: Server created - name: Server created
cs_instance: ngine_io.cloudstack.cs_instance:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
root_disk_size: "{{ disk }}" root_disk_size: "{{ disk }}"
template: "{{ image_id }}" template: "{{ image_id }}"
@ -48,12 +54,9 @@
user_data: "{{ lookup('template', 'files/cloud-init/base.yml') }}" user_data: "{{ lookup('template', 'files/cloud-init/base.yml') }}"
register: cs_server register: cs_server
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ cs_server.default_ip }}" cloud_instance_ip: "{{ cs_server.default_ip }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"
cloudinit: true cloudinit: true
environment:
CLOUDSTACK_KEY: "{{ algo_cs_key }}"
CLOUDSTACK_SECRET: "{{ algo_cs_token }}"
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"

View file

@ -1,6 +1,8 @@
--- ---
- block: - name: Prompts
- pause: block:
- name: Read API key
ansible.builtin.pause:
prompt: | prompt: |
Enter the API key (https://trailofbits.github.io/algo/cloud-cloudstack.html): Enter the API key (https://trailofbits.github.io/algo/cloud-cloudstack.html):
echo: false echo: false
@ -9,7 +11,8 @@
- cs_key is undefined - cs_key is undefined
- lookup('env','CLOUDSTACK_KEY')|length <= 0 - lookup('env','CLOUDSTACK_KEY')|length <= 0
- pause: - name: Read API secret
ansible.builtin.pause:
prompt: | prompt: |
Enter the API ssecret (https://trailofbits.github.io/algo/cloud-cloudstack.html): Enter the API ssecret (https://trailofbits.github.io/algo/cloud-cloudstack.html):
echo: false echo: false
@ -18,7 +21,8 @@
- cs_secret is undefined - cs_secret is undefined
- lookup('env','CLOUDSTACK_SECRET')|length <= 0 - lookup('env','CLOUDSTACK_SECRET')|length <= 0
- pause: - name: Read API endpoint
ansible.builtin.pause:
prompt: | prompt: |
Enter the API endpoint (https://trailofbits.github.io/algo/cloud-cloudstack.html) Enter the API endpoint (https://trailofbits.github.io/algo/cloud-cloudstack.html)
[https://api.exoscale.com/compute] [https://api.exoscale.com/compute]
@ -27,14 +31,15 @@
- cs_url is undefined - cs_url is undefined
- lookup('env', 'CLOUDSTACK_ENDPOINT') | length <= 0 - lookup('env', 'CLOUDSTACK_ENDPOINT') | length <= 0
- set_fact: - name: Set facts
ansible.builtin.set_fact:
algo_cs_key: "{{ cs_key | default(_cs_key.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_KEY'), true) }}" algo_cs_key: "{{ cs_key | default(_cs_key.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_KEY'), true) }}"
algo_cs_token: "{{ cs_secret | default(_cs_secret.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_SECRET'), true) }}" algo_cs_token: "{{ cs_secret | default(_cs_secret.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_SECRET'), true) }}"
algo_cs_url: "{{ cs_url | default(_cs_url.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_ENDPOINT'), true) | default('https://api.exoscale.com/compute',\ algo_cs_url: "{{ cs_url | default(_cs_url.user_input|default(None)) | default(lookup('env', 'CLOUDSTACK_ENDPOINT'), true) | default('https://api.exoscale.com/compute',\
\ true) }}" \ true) }}"
- name: Get zones on cloud - name: Get zones on cloud
cs_zone_info: ngine_io.cloudstack.cs_zone_info:
register: _cs_zones register: _cs_zones
environment: environment:
CLOUDSTACK_KEY: "{{ algo_cs_key }}" CLOUDSTACK_KEY: "{{ algo_cs_key }}"
@ -42,17 +47,18 @@
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}" CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
- name: Extract zones from output - name: Extract zones from output
set_fact: ansible.builtin.set_fact:
cs_zones: "{{ _cs_zones['zones'] | sort(attribute='name') }}" cs_zones: "{{ _cs_zones['zones'] | sort(attribute='name') }}"
- name: Set the default zone - name: Set the default zone
set_fact: ansible.builtin.set_fact:
default_zone: >- default_zone: >-
{% for z in cs_zones %} {% for z in cs_zones %}
{%- if z['name'] == "ch-gva-2" %}{{ loop.index }}{% endif %} {%- if z['name'] == "ch-gva-2" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read zone
ansible.builtin.pause:
prompt: | prompt: |
What zone should the server be located in? What zone should the server be located in?
{% for z in cs_zones %} {% for z in cs_zones %}

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: name:
- cs - cs
- sshpubkeys - sshpubkeys

View file

@ -1,16 +1,16 @@
--- ---
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- name: Upload the SSH key - name: Upload the SSH key
digital_ocean_sshkey: community.digitalocean.digital_ocean_sshkey:
oauth_token: "{{ algo_do_token }}" oauth_token: "{{ algo_do_token }}"
name: "{{ SSH_keys.comment }}" name: "{{ SSH_keys.comment }}"
ssh_pub_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}" ssh_pub_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
register: do_ssh_key register: do_ssh_key
- name: Creating a droplet... - name: Creating a droplet...
digital_ocean_droplet: community.digitalocean.digital_ocean_droplet:
state: present state: present
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
oauth_token: "{{ algo_do_token }}" oauth_token: "{{ algo_do_token }}"
@ -27,23 +27,26 @@
register: digital_ocean_droplet register: digital_ocean_droplet
# Return data is not idempotent # Return data is not idempotent
- set_fact: - name: Set fact
ansible.builtin.set_fact:
droplet: "{{ digital_ocean_droplet.data.droplet | default(digital_ocean_droplet.data) }}" droplet: "{{ digital_ocean_droplet.data.droplet | default(digital_ocean_droplet.data) }}"
- block: - name: Alternative ingress IP
when: alternative_ingress_ip
block:
- name: Create a Floating IP - name: Create a Floating IP
digital_ocean_floating_ip: community.digitalocean.digital_ocean_floating_ip:
state: present state: present
oauth_token: "{{ algo_do_token }}" oauth_token: "{{ algo_do_token }}"
droplet_id: "{{ droplet.id }}" droplet_id: "{{ droplet.id }}"
register: digital_ocean_floating_ip register: digital_ocean_floating_ip
- name: Set the static ip as a fact - name: Set the static ip as a fact
set_fact: ansible.builtin.set_fact:
cloud_alternative_ingress_ip: "{{ digital_ocean_floating_ip.data.floating_ip.ip }}" cloud_alternative_ingress_ip: "{{ digital_ocean_floating_ip.data.floating_ip.ip }}"
when: alternative_ingress_ip
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ (droplet.networks.v4 | selectattr('type', '==', 'public')).0.ip_address }}" cloud_instance_ip: "{{ (droplet.networks.v4 | selectattr('type', '==', 'public')).0.ip_address }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read API token
ansible.builtin.pause:
prompt: | prompt: |
Enter your API token. The token must have read and write permissions (https://cloud.digitalocean.com/settings/api/tokens): Enter your API token. The token must have read and write permissions (https://cloud.digitalocean.com/settings/api/tokens):
echo: false echo: false
@ -9,11 +10,11 @@
- lookup('env','DO_API_TOKEN')|length <= 0 - lookup('env','DO_API_TOKEN')|length <= 0
- name: Set the token as a fact - name: Set the token as a fact
set_fact: ansible.builtin.set_fact:
algo_do_token: "{{ do_token | default(_do_token.user_input|default(None)) | default(lookup('env','DO_API_TOKEN'), true) }}" algo_do_token: "{{ do_token | default(_do_token.user_input|default(None)) | default(lookup('env','DO_API_TOKEN'), true) }}"
- name: Get regions - name: Get regions
uri: ansible.builtin.uri:
url: https://api.digitalocean.com/v2/regions url: https://api.digitalocean.com/v2/regions
method: GET method: GET
status_code: 200 status_code: 200
@ -23,17 +24,18 @@
register: _do_regions register: _do_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: ansible.builtin.set_fact:
do_regions: "{{ _do_regions.json.regions | selectattr('available', 'true') | sort(attribute='slug') }}" do_regions: "{{ _do_regions.json.regions | selectattr('available', 'true') | sort(attribute='slug') }}"
- name: Set default region - name: Set default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in do_regions %} {% for r in do_regions %}
{%- if r['slug'] == "nyc3" %}{{ loop.index }}{% endif %} {%- if r['slug'] == "nyc3" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
{% for r in do_regions %} {% for r in do_regions %}
@ -46,7 +48,7 @@
when: region is undefined when: region is undefined
- name: Set additional facts - name: Set additional facts
set_fact: ansible.builtin.set_fact:
algo_do_region: >- algo_do_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ do_regions[_algo_region.user_input | int -1 ]['slug'] }} {%- elif _algo_region.user_input %}{{ do_regions[_algo_region.user_input | int -1 ]['slug'] }}

View file

@ -1,6 +1,6 @@
--- ---
- name: Deploy the template - name: Deploy the template
cloudformation: amazon.aws.cloudformation:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
stack_name: "{{ stack_name }}" stack_name: "{{ stack_name }}"

View file

@ -1,12 +1,12 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- name: Locate official AMI for region - name: Locate official AMI for region
ec2_ami_info: amazon.aws.ec2_ami_info:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
owners: "{{ cloud_providers.ec2.image.owner }}" owners: "{{ cloud_providers.ec2.image.owner }}"
@ -17,13 +17,14 @@
register: ami_search register: ami_search
- name: Set the ami id as a fact - name: Set the ami id as a fact
set_fact: ansible.builtin.set_fact:
ami_image: "{{ (ami_search.images | sort(attribute='creation_date') | last)['image_id'] }}" ami_image: "{{ (ami_search.images | sort(attribute='creation_date') | last)['image_id'] }}"
- name: Deploy the stack - name: Deploy the stack
import_tasks: cloudformation.yml ansible.builtin.import_tasks: cloudformation.yml
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ stack.stack_outputs.ElasticIP }}" cloud_instance_ip: "{{ stack.stack_outputs.ElasticIP }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read access key ID
ansible.builtin.pause:
prompt: | prompt: |
Enter your AWS Access Key ID (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) Enter your AWS Access Key ID (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
Note: Make sure to use an IAM user with an acceptable policy attached (see https://github.com/trailofbits/algo/blob/master/docs/deploy-from-ansible.md) Note: Make sure to use an IAM user with an acceptable policy attached (see https://github.com/trailofbits/algo/blob/master/docs/deploy-from-ansible.md)
@ -9,7 +10,8 @@
- aws_access_key is undefined - aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0 - lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
- pause: - name: Read secret access key
ansible.builtin.pause:
prompt: | prompt: |
Enter your AWS Secret Access Key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) Enter your AWS Secret Access Key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
echo: false echo: false
@ -18,30 +20,34 @@
- aws_secret_key is undefined - aws_secret_key is undefined
- lookup('env','AWS_SECRET_ACCESS_KEY')|length <= 0 - lookup('env','AWS_SECRET_ACCESS_KEY')|length <= 0
- set_fact: - name: Set facts
ansible.builtin.set_fact:
access_key: "{{ aws_access_key | default(_aws_access_key.user_input|default(None)) | default(lookup('env','AWS_ACCESS_KEY_ID'), true) }}" access_key: "{{ aws_access_key | default(_aws_access_key.user_input|default(None)) | default(lookup('env','AWS_ACCESS_KEY_ID'), true) }}"
secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}" secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}"
- block: - name: Prompt region
when: region is undefined
block:
- name: Get regions - name: Get regions
aws_region_info: community.aws.aws_region_info:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
region: us-east-1 region: us-east-1
register: _aws_regions register: _aws_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: ansible.builtin.set_fact:
aws_regions: "{{ _aws_regions.regions | sort(attribute='region_name') }}" aws_regions: "{{ _aws_regions.regions | sort(attribute='region_name') }}"
- name: Set the default region - name: Set the default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in aws_regions %} {% for r in aws_regions %}
{%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif %} {%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
(https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region) (https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region)
@ -52,28 +58,31 @@
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _algo_region register: _algo_region
when: region is undefined
- name: Set algo_region and stack_name facts - name: Set algo_region and stack_name facts
set_fact: ansible.builtin.set_fact:
algo_region: >- algo_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ aws_regions[_algo_region.user_input | int -1 ]['region_name'] }} {%- elif _algo_region.user_input %}{{ aws_regions[_algo_region.user_input | int -1 ]['region_name'] }}
{%- else %}{{ aws_regions[default_region | int - 1]['region_name'] }}{% endif %} {%- else %}{{ aws_regions[default_region | int - 1]['region_name'] }}{% endif %}
stack_name: "{{ algo_server_name | replace('.', '-') }}" stack_name: "{{ algo_server_name | replace('.', '-') }}"
- block: - name: Use existing eip
when: cloud_providers.ec2.use_existing_eip
block:
- name: Get existing available Elastic IPs - name: Get existing available Elastic IPs
ec2_eip_info: amazon.aws.ec2_eip_info:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
region: "{{ algo_region }}" region: "{{ algo_region }}"
register: raw_eip_addresses register: raw_eip_addresses
- set_fact: - name: Set fact
ansible.builtin.set_fact:
available_eip_addresses: "{{ raw_eip_addresses.addresses | selectattr('association_id', 'undefined') | list }}" available_eip_addresses: "{{ raw_eip_addresses.addresses | selectattr('association_id', 'undefined') | list }}"
- pause: - name: Read Elastic IP
ansible.builtin.pause:
prompt: >- prompt: >-
What Elastic IP would you like to use? What Elastic IP would you like to use?
{% for eip in available_eip_addresses %} {% for eip in available_eip_addresses %}
@ -83,6 +92,6 @@
Enter the number of your desired Elastic IP Enter the number of your desired Elastic IP
register: _use_existing_eip register: _use_existing_eip
- set_fact: - name: Set fact
ansible.builtin.set_fact:
existing_eip: "{{ available_eip_addresses[_use_existing_eip.user_input | int -1 ]['allocation_id'] }}" existing_eip: "{{ available_eip_addresses[_use_existing_eip.user_input | int -1 ]['allocation_id'] }}"
when: cloud_providers.ec2.use_existing_eip

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: name:
- boto>=2.5 - boto>=2.5
- boto3 - boto3

View file

@ -1,12 +1,12 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- name: Network configured - name: Network configured
gcp_compute_network: google.cloud.gcp_compute_network:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
@ -17,7 +17,7 @@
register: gcp_compute_network register: gcp_compute_network
- name: Firewall configured - name: Firewall configured
gcp_compute_firewall: google.cloud.gcp_compute_firewall:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
@ -35,9 +35,11 @@
- "{{ ssh_port }}" - "{{ ssh_port }}"
- ip_protocol: icmp - ip_protocol: icmp
- block: - name: External IP
when: cloud_providers.gce.external_static_ip
block:
- name: External IP allocated - name: External IP allocated
gcp_compute_address: google.cloud.gcp_compute_address:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
@ -46,12 +48,11 @@
register: gcp_compute_address register: gcp_compute_address
- name: Set External IP as a fact - name: Set External IP as a fact
set_fact: ansible.builtin.set_fact:
external_ip: "{{ gcp_compute_address.address }}" external_ip: "{{ gcp_compute_address.address }}"
when: cloud_providers.gce.external_static_ip
- name: Instance created - name: Instance created
gcp_compute_instance: google.cloud.gcp_compute_instance:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
@ -77,7 +78,8 @@
- environment-algo - environment-algo
register: gcp_compute_instance register: gcp_compute_instance
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ gcp_compute_instance.networkInterfaces[0].accessConfigs[0].natIP }}" cloud_instance_ip: "{{ gcp_compute_instance.networkInterfaces[0].accessConfigs[0].natIP }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read credentials filepath
ansible.builtin.pause:
prompt: | prompt: |
Enter the local path to your credentials JSON file Enter the local path to your credentials JSON file
(https://support.google.com/cloud/answer/6158849?hl=en&ref_topic=6262490#serviceaccounts) (https://support.google.com/cloud/answer/6158849?hl=en&ref_topic=6262490#serviceaccounts)
@ -8,21 +9,26 @@
- gce_credentials_file is undefined - gce_credentials_file is undefined
- lookup('env','GCE_CREDENTIALS_FILE_PATH')|length <= 0 - lookup('env','GCE_CREDENTIALS_FILE_PATH')|length <= 0
- set_fact: - name: Set facts
ansible.builtin.set_fact:
credentials_file_path: "{{ gce_credentials_file | default(_gce_credentials_file.user_input|default(None)) | default(lookup('env','GCE_CREDENTIALS_FILE_PATH'),\ credentials_file_path: "{{ gce_credentials_file | default(_gce_credentials_file.user_input|default(None)) | default(lookup('env','GCE_CREDENTIALS_FILE_PATH'),\
\ true) }}" \ true) }}"
ssh_public_key_lookup: "{{ lookup('file', '{{ SSH_keys.public }}') }}" ssh_public_key_lookup: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
- set_fact: - name: Set fact
ansible.builtin.set_fact:
credentials_file_lookup: "{{ lookup('file', '{{ credentials_file_path }}') }}" credentials_file_lookup: "{{ lookup('file', '{{ credentials_file_path }}') }}"
- set_fact: - name: Set facts
ansible.builtin.set_fact:
service_account_email: "{{ credentials_file_lookup.client_email | default(lookup('env','GCE_EMAIL')) }}" service_account_email: "{{ credentials_file_lookup.client_email | default(lookup('env','GCE_EMAIL')) }}"
project_id: "{{ credentials_file_lookup.project_id | default(lookup('env','GCE_PROJECT')) }}" project_id: "{{ credentials_file_lookup.project_id | default(lookup('env','GCE_PROJECT')) }}"
- block: - name: Region undefined
when: region is undefined
block:
- name: Get regions - name: Get regions
gcp_compute_location_info: google.cloud.gcp_compute_location_info:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
@ -31,20 +37,21 @@
register: gcp_compute_regions_info register: gcp_compute_regions_info
- name: Set facts about the regions - name: Set facts about the regions
set_fact: ansible.builtin.set_fact:
gce_regions: >- gce_regions: >-
[{%- for region in gcp_compute_regions_info.resources | sort(attribute='name') -%} [{%- for region in gcp_compute_regions_info.resources | sort(attribute='name') -%}
'{{ region.name }}'{% if not loop.last %},{% endif %} '{{ region.name }}'{% if not loop.last %},{% endif %}
{%- endfor -%}] {%- endfor -%}]
- name: Set facts about the default region - name: Set facts about the default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for region in gce_regions %} {% for region in gce_regions %}
{%- if region == "us-east1" %}{{ loop.index }}{% endif %} {%- if region == "us-east1" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
(https://cloud.google.com/compute/docs/regions-zones/#locations) (https://cloud.google.com/compute/docs/regions-zones/#locations)
@ -55,17 +62,16 @@
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _gce_region register: _gce_region
when: region is undefined
- name: Set region as a fact - name: Set region as a fact
set_fact: ansible.builtin.set_fact:
algo_region: >- algo_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _gce_region.user_input %}{{ gce_regions[_gce_region.user_input | int -1 ] }} {%- elif _gce_region.user_input %}{{ gce_regions[_gce_region.user_input | int -1 ] }}
{%- else %}{{ gce_regions[default_region | int - 1] }}{% endif %} {%- else %}{{ gce_regions[default_region | int - 1] }}{% endif %}
- name: Get zones - name: Get zones
gcp_compute_location_info: google.cloud.gcp_compute_location_info:
auth_kind: serviceaccount auth_kind: serviceaccount
service_account_file: "{{ credentials_file_path }}" service_account_file: "{{ credentials_file_path }}"
project: "{{ project_id }}" project: "{{ project_id }}"
@ -76,5 +82,5 @@
register: gcp_compute_zone_info register: gcp_compute_zone_info
- name: Set random available zone as a fact - name: Set random available zone as a fact
set_fact: ansible.builtin.set_fact:
algo_zone: "{{ (gcp_compute_zone_info.resources | random(seed=algo_server_name + algo_region + project_id) ).name }}" algo_zone: "{{ (gcp_compute_zone_info.resources | random(seed=algo_server_name + algo_region + project_id) ).name }}"

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: name:
- requests>=2.18.4 - requests>=2.18.4
- google-auth>=1.3.0 - google-auth>=1.3.0

View file

@ -1,12 +1,12 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- name: Create an ssh key - name: Create an ssh key
hcloud_ssh_key: hetzner.hcloud.hcloud_ssh_key:
name: algo-{{ 999999 | random(seed=lookup('file', SSH_keys.public)) }} name: algo-{{ 999999 | random(seed=lookup('file', SSH_keys.public)) }}
public_key: "{{ lookup('file', SSH_keys.public) }}" public_key: "{{ lookup('file', SSH_keys.public) }}"
state: present state: present
@ -14,7 +14,7 @@
register: hcloud_ssh_key register: hcloud_ssh_key
- name: Create a server... - name: Create a server...
hcloud_server: hetzner.hcloud.hcloud_server:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
location: "{{ algo_hcloud_region }}" location: "{{ algo_hcloud_region }}"
server_type: "{{ cloud_providers.hetzner.server_type }}" server_type: "{{ cloud_providers.hetzner.server_type }}"
@ -27,7 +27,8 @@
Environment: algo Environment: algo
register: hcloud_server register: hcloud_server
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ hcloud_server.hcloud_server.ipv4_address }}" cloud_instance_ip: "{{ hcloud_server.hcloud_server.ipv4_address }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read API token
ansible.builtin.pause:
prompt: | prompt: |
Enter your API token (https://trailofbits.github.io/algo/cloud-hetzner.html#api-token): Enter your API token (https://trailofbits.github.io/algo/cloud-hetzner.html#api-token):
echo: false echo: false
@ -9,26 +10,27 @@
- lookup('env','HCLOUD_TOKEN')|length <= 0 - lookup('env','HCLOUD_TOKEN')|length <= 0
- name: Set the token as a fact - name: Set the token as a fact
set_fact: ansible.builtin.set_fact:
algo_hcloud_token: "{{ hcloud_token | default(_hcloud_token.user_input|default(None)) | default(lookup('env','HCLOUD_TOKEN'), true) }}" algo_hcloud_token: "{{ hcloud_token | default(_hcloud_token.user_input|default(None)) | default(lookup('env','HCLOUD_TOKEN'), true) }}"
- name: Get regions - name: Get regions
hcloud_datacenter_facts: hetzner.hcloud.hcloud_datacenter_info:
api_token: "{{ algo_hcloud_token }}" api_token: "{{ algo_hcloud_token }}"
register: _hcloud_regions register: _hcloud_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: ansible.builtin.set_fact:
hcloud_regions: "{{ hcloud_datacenter_facts | sort(attribute='location') }}" hcloud_regions: "{{ hcloud_datacenter_facts | sort(attribute='location') }}"
- name: Set default region - name: Set default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in hcloud_regions %} {% for r in hcloud_regions %}
{%- if r['location'] == "nbg1" %}{{ loop.index }}{% endif %} {%- if r['location'] == "nbg1" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
{% for r in hcloud_regions %} {% for r in hcloud_regions %}
@ -41,7 +43,7 @@
when: region is undefined when: region is undefined
- name: Set additional facts - name: Set additional facts
set_fact: ansible.builtin.set_fact:
algo_hcloud_region: >- algo_hcloud_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ hcloud_regions[_algo_region.user_input | int -1 ]['location'] }} {%- elif _algo_region.user_input %}{{ hcloud_regions[_algo_region.user_input | int -1 ]['location'] }}

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: name:
- hcloud - hcloud
state: latest state: latest

View file

@ -1,6 +1,6 @@
--- ---
- name: Deploy the template - name: Deploy the template
cloudformation: amazon.aws.cloudformation:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
stack_name: "{{ stack_name }}" stack_name: "{{ stack_name }}"

View file

@ -1,14 +1,15 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- name: Deploy the stack - name: Deploy the stack
import_tasks: cloudformation.yml ansible.builtin.import_tasks: cloudformation.yml
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ stack.stack_outputs.IpAddress }}" cloud_instance_ip: "{{ stack.stack_outputs.IpAddress }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read access key
ansible.builtin.pause:
prompt: | prompt: |
Enter your aws_access_key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) Enter your aws_access_key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
Note: Make sure to use an IAM user with an acceptable policy attached (see https://github.com/trailofbits/algo/blob/master/docs/deploy-from-ansible.md) Note: Make sure to use an IAM user with an acceptable policy attached (see https://github.com/trailofbits/algo/blob/master/docs/deploy-from-ansible.md)
@ -9,7 +10,8 @@
- aws_access_key is undefined - aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0 - lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
- pause: - name: Read secret key
ansible.builtin.pause:
prompt: | prompt: |
Enter your aws_secret_key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html) Enter your aws_secret_key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
echo: false echo: false
@ -18,30 +20,34 @@
- aws_secret_key is undefined - aws_secret_key is undefined
- lookup('env','AWS_SECRET_ACCESS_KEY')|length <= 0 - lookup('env','AWS_SECRET_ACCESS_KEY')|length <= 0
- set_fact: - name: Set facts
ansible.builtin.set_fact:
access_key: "{{ aws_access_key | default(_aws_access_key.user_input|default(None)) | default(lookup('env','AWS_ACCESS_KEY_ID'), true) }}" access_key: "{{ aws_access_key | default(_aws_access_key.user_input|default(None)) | default(lookup('env','AWS_ACCESS_KEY_ID'), true) }}"
secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}" secret_key: "{{ aws_secret_key | default(_aws_secret_key.user_input|default(None)) | default(lookup('env','AWS_SECRET_ACCESS_KEY'), true) }}"
- block: - name: region undefined
when: region is undefined
block:
- name: Get regions - name: Get regions
lightsail_region_facts: community.aws.aws_region_info:
aws_access_key: "{{ access_key }}" aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}" aws_secret_key: "{{ secret_key }}"
region: us-east-1 region: us-east-1
register: _lightsail_regions register: _lightsail_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: ansible.builtin.set_fact:
lightsail_regions: "{{ _lightsail_regions.data.regions | sort(attribute='name') }}" lightsail_regions: "{{ _lightsail_regions.data.regions | sort(attribute='name') }}"
- name: Set the default region - name: Set the default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in lightsail_regions %} {% for r in lightsail_regions %}
{%- if r['name'] == "us-east-1" %}{{ loop.index }}{% endif %} {%- if r['name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
(https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/) (https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)
@ -52,9 +58,9 @@
Enter the number of your desired region Enter the number of your desired region
[{{ default_region }}] [{{ default_region }}]
register: _algo_region register: _algo_region
when: region is undefined
- set_fact: - name: Set facts
ansible.builtin.set_fact:
stack_name: "{{ algo_server_name | replace('.', '-') }}" stack_name: "{{ algo_server_name | replace('.', '-') }}"
algo_region: >- algo_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: name:
- boto>=2.5 - boto>=2.5
- boto3 - boto3

View file

@ -1,44 +1,19 @@
--- ---
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- name: Set facts - name: Set facts
set_fact: ansible.builtin.set_fact:
stackscript: | stackscript: |
{{ lookup('template', 'files/cloud-init/base.sh') }} {{ lookup('template', 'files/cloud-init/base.sh') }}
mkdir -p /var/lib/cloud/data/ || true mkdir -p /var/lib/cloud/data/ || true
touch /var/lib/cloud/data/result.json touch /var/lib/cloud/data/result.json
- name: Create a stackscript
linode_stackscript_v4:
access_token: "{{ algo_linode_token }}"
label: "{{ algo_server_name }}"
state: present
description: Environment:Algo
images:
- "{{ cloud_providers.linode.image }}"
script: |
{{ stackscript }}
register: _linode_stackscript
- name: Update the stackscript
uri:
url: https://api.linode.com/v4/linode/stackscripts/{{ _linode_stackscript.stackscript.id }}
method: PUT
body_format: json
body:
script: |
{{ stackscript }}
headers:
Content-Type: application/json
Authorization: Bearer {{ algo_linode_token }}
when: (_linode_stackscript.stackscript.script | hash('md5')) != (stackscript | hash('md5'))
- name: Creating an instance... - name: Creating an instance...
linode_v4: community.general.linode_v4:
access_token: "{{ algo_linode_token }}" access_token: "{{ algo_linode_token }}"
label: "{{ algo_server_name }}" label: "{{ algo_server_name }}"
state: present state: present
@ -46,10 +21,12 @@
image: "{{ cloud_providers.linode.image }}" image: "{{ cloud_providers.linode.image }}"
type: "{{ cloud_providers.linode.type }}" type: "{{ cloud_providers.linode.type }}"
authorized_keys: "{{ public_key }}" authorized_keys: "{{ public_key }}"
stackscript_id: "{{ _linode_stackscript.stackscript.id }}" stackscript_data: |
{{ stackscript }}
register: _linode register: _linode
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ _linode.instance.ipv4[0] }}" cloud_instance_ip: "{{ _linode.instance.ipv4[0] }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read
ansible.builtin.pause:
prompt: | prompt: |
Enter your ACCESS token. (https://developers.linode.com/api/v4/#access-and-authentication): Enter your ACCESS token. (https://developers.linode.com/api/v4/#access-and-authentication):
echo: false echo: false
@ -9,28 +10,29 @@
- lookup('env','LINODE_API_TOKEN')|length <= 0 - lookup('env','LINODE_API_TOKEN')|length <= 0
- name: Set the token as a fact - name: Set the token as a fact
set_fact: ansible.builtin.set_fact:
algo_linode_token: "{{ linode_token | default(_linode_token.user_input|default(None)) | default(lookup('env','LINODE_API_TOKEN'), true) }}" algo_linode_token: "{{ linode_token | default(_linode_token.user_input|default(None)) | default(lookup('env','LINODE_API_TOKEN'), true) }}"
- name: Get regions - name: Get regions
uri: ansible.builtin.uri:
url: https://api.linode.com/v4/regions url: https://api.linode.com/v4/regions
method: GET method: GET
status_code: 200 status_code: 200
register: _linode_regions register: _linode_regions
- name: Set facts about the regions - name: Set facts about the regions
set_fact: ansible.builtin.set_fact:
linode_regions: "{{ _linode_regions.json.data | sort(attribute='id') }}" linode_regions: "{{ _linode_regions.json.data | sort(attribute='id') }}"
- name: Set default region - name: Set default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in linode_regions %} {% for r in linode_regions %}
{%- if r['id'] == "us-east" %}{{ loop.index }}{% endif %} {%- if r['id'] == "us-east" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
{% for r in linode_regions %} {% for r in linode_regions %}
@ -43,7 +45,7 @@
when: region is undefined when: region is undefined
- name: Set additional facts - name: Set additional facts
set_fact: ansible.builtin.set_fact:
algo_linode_region: >- algo_linode_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ linode_regions[_algo_region.user_input | int -1 ]['id'] }} {%- elif _algo_region.user_input %}{{ linode_regions[_algo_region.user_input | int -1 ]['id'] }}

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: name:
- linode_api4 - linode_api4
state: latest state: latest

View file

@ -1,10 +1,11 @@
--- ---
- fail: - name: Fail on credentials
ansible.builtin.fail:
msg: "OpenStack credentials are not set. Download it from the OpenStack dashboard->Compute->API Access and source it in the shell (eg: source /tmp/dhc-openrc.sh)" msg: "OpenStack credentials are not set. Download it from the OpenStack dashboard->Compute->API Access and source it in the shell (eg: source /tmp/dhc-openrc.sh)"
when: lookup('env', 'OS_AUTH_URL')|length <= 0 when: lookup('env', 'OS_AUTH_URL')|length <= 0
- name: Build python virtual environment - name: Build python virtual environment
import_tasks: venv.yml ansible.builtin.import_tasks: venv.yml
- name: Security group created - name: Security group created
openstack.cloud.security_group: openstack.cloud.security_group:
@ -38,7 +39,7 @@
register: os_image register: os_image
- name: Set image as a fact - name: Set image as a fact
set_fact: ansible.builtin.set_fact:
image_id: "{{ item.id }}" image_id: "{{ item.id }}"
loop: "{{ os_image.openstack_image }}" loop: "{{ os_image.openstack_image }}"
when: when:
@ -50,7 +51,7 @@
register: os_network register: os_network
- name: Set the network as a fact - name: Set the network as a fact
set_fact: ansible.builtin.set_fact:
public_network_id: "{{ item.id }}" public_network_id: "{{ item.id }}"
when: when:
- item['router:external']|default(omit) - item['router:external']|default(omit)
@ -59,7 +60,7 @@
with_items: "{{ os_network.openstack_networks }}" with_items: "{{ os_network.openstack_networks }}"
- name: Set facts - name: Set facts
set_fact: ansible.builtin.set_fact:
flavor_id: "{{ (os_flavor.openstack_flavors | sort(attribute='ram'))[0]['id'] }}" flavor_id: "{{ (os_flavor.openstack_flavors | sort(attribute='ram'))[0]['id'] }}"
security_group_name: "{{ os_security_group['secgroup']['name'] }}" security_group_name: "{{ os_security_group['secgroup']['name'] }}"
@ -75,7 +76,8 @@
- net-id: "{{ public_network_id }}" - net-id: "{{ public_network_id }}"
register: os_server register: os_server
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ os_server['openstack']['public_v4'] }}" cloud_instance_ip: "{{ os_server['openstack']['public_v4'] }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,6 +1,6 @@
--- ---
- name: Install requirements - name: Install requirements
pip: ansible.builtin.pip:
name: shade name: shade
state: latest state: latest
virtualenv_python: python3 virtualenv_python: python3

View file

@ -1,19 +1,24 @@
--- ---
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- block: - name: Scaleway
environment:
SCW_TOKEN: "{{ algo_scaleway_token }}"
block:
- name: Gather Scaleway organizations facts - name: Gather Scaleway organizations facts
scaleway_organization_info: community.general.scaleway_organization_info:
api_token: "{{ algo_scaleway_token }}"
register: scaleway_org register: scaleway_org
- name: Get images - name: Get images
scaleway_image_info: community.general.scaleway_image_info:
region: "{{ algo_region }}" region: "{{ algo_region }}"
api_token: "{{ algo_scaleway_token }}"
register: scaleway_image register: scaleway_image
- name: Set cloud specific facts - name: Set cloud specific facts
set_fact: ansible.builtin.set_fact:
organization_id: "{{ scaleway_org.scaleway_organization_info[0]['id'] }}" organization_id: "{{ scaleway_org.scaleway_organization_info[0]['id'] }}"
images: >- images: >-
[{% for i in scaleway_image.scaleway_image_info -%} [{% for i in scaleway_image.scaleway_image_info -%}
@ -24,7 +29,8 @@
{%- endfor -%}] {%- endfor -%}]
- name: Create a server - name: Create a server
scaleway_compute: community.general.scaleway_compute:
api_token: "{{ algo_scaleway_token }}"
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
enable_ipv6: true enable_ipv6: true
public_ip: dynamic public_ip: dynamic
@ -41,7 +47,7 @@
register: scaleway_compute register: scaleway_compute
- name: Patch the cloud-init - name: Patch the cloud-init
uri: ansible.builtin.uri:
url: https://cp-{{ algo_region }}.scaleway.com/servers/{{ scaleway_compute.msg.id }}/user_data/cloud-init url: https://cp-{{ algo_region }}.scaleway.com/servers/{{ scaleway_compute.msg.id }}/user_data/cloud-init
method: PATCH method: PATCH
body: "{{ lookup('template', 'files/cloud-init/base.yml') }}" body: "{{ lookup('template', 'files/cloud-init/base.yml') }}"
@ -51,7 +57,8 @@
X-Auth-Token: "{{ algo_scaleway_token }}" X-Auth-Token: "{{ algo_scaleway_token }}"
- name: Start the server - name: Start the server
scaleway_compute: community.general.scaleway_compute:
api_token: "{{ algo_scaleway_token }}"
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
enable_ipv6: true enable_ipv6: true
public_ip: dynamic public_ip: dynamic
@ -69,10 +76,9 @@
until: algo_instance.msg.public_ip until: algo_instance.msg.public_ip
retries: 3 retries: 3
delay: 3 delay: 3
environment:
SCW_TOKEN: "{{ algo_scaleway_token }}"
- set_fact: - name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ algo_instance.msg.public_ip.address }}" cloud_instance_ip: "{{ algo_instance.msg.public_ip.address }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read auth token
ansible.builtin.pause:
prompt: | prompt: |
Enter your auth token (https://trailofbits.github.io/algo/cloud-scaleway.html) Enter your auth token (https://trailofbits.github.io/algo/cloud-scaleway.html)
echo: false echo: false
@ -8,7 +9,8 @@
- scaleway_token is undefined - scaleway_token is undefined
- lookup('env','SCW_TOKEN')|length <= 0 - lookup('env','SCW_TOKEN')|length <= 0
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
{% for r in scaleway_regions %} {% for r in scaleway_regions %}
@ -21,7 +23,7 @@
when: region is undefined when: region is undefined
- name: Set scaleway facts - name: Set scaleway facts
set_fact: ansible.builtin.set_fact:
algo_scaleway_token: "{{ scaleway_token | default(_scaleway_token.user_input) | default(lookup('env','SCW_TOKEN'), true) }}" algo_scaleway_token: "{{ scaleway_token | default(_scaleway_token.user_input) | default(lookup('env','SCW_TOKEN'), true) }}"
algo_region: >- algo_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}

View file

@ -1,14 +1,17 @@
--- ---
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml
- block: - name: Vultr setup
environment:
VULTR_API_CONFIG: "{{ algo_vultr_config }}"
block:
- name: Creating a firewall group - name: Creating a firewall group
vultr_firewall_group: vultr.cloud.firewall_group:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
- name: Creating firewall rules - name: Creating firewall rules
vultr_firewall_rule: vultr.cloud.firewall_rule:
group: "{{ algo_server_name }}" group: "{{ algo_server_name }}"
protocol: "{{ item.protocol }}" protocol: "{{ item.protocol }}"
port: "{{ item.port }}" port: "{{ item.port }}"
@ -25,13 +28,13 @@
- { protocol: udp, port: "{{ wireguard_port }}", ip: v6, cidr: "::/0" } - { protocol: udp, port: "{{ wireguard_port }}", ip: v6, cidr: "::/0" }
- name: Upload the startup script - name: Upload the startup script
vultr_startup_script: vultr.cloud.startup_script:
name: algo-startup name: algo-startup
script: | script: |
{{ lookup('template', 'files/cloud-init/base.yml') }} {{ lookup('template', 'files/cloud-init/base.yml') }}
- name: Creating a server - name: Creating a server
vultr_server: vultr.cloud.vpc:
name: "{{ algo_server_name }}" name: "{{ algo_server_name }}"
startup_script: algo-startup startup_script: algo-startup
hostname: "{{ algo_server_name }}" hostname: "{{ algo_server_name }}"
@ -46,11 +49,9 @@
notify_activate: false notify_activate: false
register: vultr_server register: vultr_server
- set_fact: - name: Set fact vultr
ansible.builtin.set_fact:
cloud_instance_ip: "{{ vultr_server.vultr_server.v4_main_ip }}" cloud_instance_ip: "{{ vultr_server.vultr_server.v4_main_ip }}"
ansible_ssh_user: algo ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}" ansible_ssh_port: "{{ ssh_port }}"
cloudinit: true cloudinit: true
environment:
VULTR_API_CONFIG: "{{ algo_vultr_config }}"

View file

@ -1,5 +1,6 @@
--- ---
- pause: - name: Read configuration ini
ansible.builtin.pause:
prompt: | prompt: |
Enter the local path to your configuration INI file Enter the local path to your configuration INI file
(https://trailofbits.github.io/algo/cloud-vultr.html): (https://trailofbits.github.io/algo/cloud-vultr.html):
@ -9,35 +10,36 @@
- lookup('env','VULTR_API_CONFIG')|length <= 0 - lookup('env','VULTR_API_CONFIG')|length <= 0
- name: Set the token as a fact - name: Set the token as a fact
set_fact: ansible.builtin.set_fact:
algo_vultr_config: "{{ vultr_config | default(_vultr_config.user_input) | default(lookup('env','VULTR_API_CONFIG'), true) }}" algo_vultr_config: "{{ vultr_config | default(_vultr_config.user_input) | default(lookup('env','VULTR_API_CONFIG'), true) }}"
- name: Get regions - name: Get regions
uri: ansible.builtin.uri:
url: https://api.vultr.com/v1/regions/list url: https://api.vultr.com/v1/regions/list
method: GET method: GET
status_code: 200 status_code: 200
register: _vultr_regions register: _vultr_regions
- name: Format regions - name: Format regions
set_fact: ansible.builtin.set_fact:
regions: >- regions: >-
[ {% for k, v in _vultr_regions.json.items() %} [ {% for k, v in _vultr_regions.json.items() %}
{{ v }}{% if not loop.last %},{% endif %} {{ v }}{% if not loop.last %},{% endif %}
{% endfor %} ] {% endfor %} ]
- name: Set regions as a fact - name: Set regions as a fact
set_fact: ansible.builtin.set_fact:
vultr_regions: "{{ regions | sort(attribute='country') }}" vultr_regions: "{{ regions | sort(attribute='country') }}"
- name: Set default region - name: Set default region
set_fact: ansible.builtin.set_fact:
default_region: >- default_region: >-
{% for r in vultr_regions %} {% for r in vultr_regions %}
{%- if r['DCID'] == "1" %}{{ loop.index }}{% endif %} {%- if r['DCID'] == "1" %}{{ loop.index }}{% endif %}
{%- endfor %} {%- endfor %}
- pause: - name: Read region
ansible.builtin.pause:
prompt: | prompt: |
What region should the server be located in? What region should the server be located in?
(https://www.vultr.com/locations/): (https://www.vultr.com/locations/):
@ -51,7 +53,7 @@
when: region is undefined when: region is undefined
- name: Set the desired region as a fact - name: Set the desired region as a fact
set_fact: ansible.builtin.set_fact:
algo_vultr_region: >- algo_vultr_region: >-
{% if region is defined %}{{ region }} {% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ vultr_regions[_algo_region.user_input | int -1 ]['name'] }} {%- elif _algo_region.user_input %}{{ vultr_regions[_algo_region.user_input | int -1 ]['name'] }}

View file

@ -7,3 +7,6 @@ ipv6_default: "{{ ansible_default_ipv6.address + '/' + ansible_default_ipv6.pref
ipv6_subnet_size: "{{ ipv6_default | ipaddr('size') }}" ipv6_subnet_size: "{{ ipv6_default | ipaddr('size') }}"
ipv6_egress_ip: >- ipv6_egress_ip: >-
{{ (ipv6_default | next_nth_usable(15 | random(seed=algo_server_name + ansible_fqdn))) + '/124' if ipv6_subnet_size|int > 1 else ipv6_default }} {{ (ipv6_default | next_nth_usable(15 | random(seed=algo_server_name + ansible_fqdn))) + '/124' if ipv6_subnet_size|int > 1 else ipv6_default }}
# as used in common role
wireguard_port_avoid: 53

View file

@ -1,3 +1,3 @@
--- ---
- name: Include prompts - name: Include prompts
import_tasks: prompts.yml ansible.builtin.import_tasks: prompts.yml

View file

@ -1,17 +1,18 @@
--- ---
- pause: - name: Starting warning
prompt: "{{ item }}" ansible.builtin.pause:
when: not tests|default(false)|bool prompt: |
tags:
- skip_ansible_lint
with_items: |
https://trailofbits.github.io/algo/deploy-to-ubuntu.html https://trailofbits.github.io/algo/deploy-to-ubuntu.html
Local installation might break your server. Use at your own risk. Local installation might break your server. Use at your own risk.
Proceed? Press ENTER to continue or CTRL+C and A to abort... Proceed? Press ENTER to continue or CTRL+C and A to abort...
when: not tests|default(false)|bool
tags:
- skip_ansible_lint
- pause: - name: Read IP address
ansible.builtin.pause:
prompt: | prompt: |
Enter the IP address of your server: (or use localhost for local installation): Enter the IP address of your server: (or use localhost for local installation):
[localhost] [localhost]
@ -19,14 +20,17 @@
when: server is undefined when: server is undefined
- name: Set the facts - name: Set the facts
set_fact: ansible.builtin.set_fact:
cloud_instance_ip: >- cloud_instance_ip: >-
{% if server is defined %}{{ server }} {% if server is defined %}{{ server }}
{%- elif _algo_server.user_input %}{{ _algo_server.user_input }} {%- elif _algo_server.user_input %}{{ _algo_server.user_input }}
{%- else %}localhost{% endif %} {%- else %}localhost{% endif %}
- block: - name: Var cloud_instance_ip not localhost
- pause: when: cloud_instance_ip != "localhost"
block:
- name: Read user
ansible.builtin.pause:
prompt: | prompt: |
What user should we use to login on the server? (note: passwordless login required, or ignore if you're deploying to localhost) What user should we use to login on the server? (note: passwordless login required, or ignore if you're deploying to localhost)
[root] [root]
@ -34,14 +38,14 @@
when: ssh_user is undefined when: ssh_user is undefined
- name: Set the facts - name: Set the facts
set_fact: ansible.builtin.set_fact:
ansible_ssh_user: >- ansible_ssh_user: >-
{% if ssh_user is defined %}{{ ssh_user }} {% if ssh_user is defined %}{{ ssh_user }}
{%- elif _algo_ssh_user.user_input %}{{ _algo_ssh_user.user_input }} {%- elif _algo_ssh_user.user_input %}{{ _algo_ssh_user.user_input }}
{%- else %}root{% endif %} {%- else %}root{% endif %}
when: cloud_instance_ip != "localhost"
- pause: - name: Read public IP address
ansible.builtin.pause:
prompt: | prompt: |
Enter the public IP address or domain name of your server: (IMPORTANT! This is used to verify the certificate) Enter the public IP address or domain name of your server: (IMPORTANT! This is used to verify the certificate)
[{{ cloud_instance_ip }}] [{{ cloud_instance_ip }}]
@ -49,7 +53,7 @@
when: endpoint is undefined when: endpoint is undefined
- name: Set the facts - name: Set the facts
set_fact: ansible.builtin.set_fact:
IP_subject_alt_name: >- IP_subject_alt_name: >-
{% if endpoint is defined %}{{ endpoint }} {% if endpoint is defined %}{{ endpoint }}
{%- elif _endpoint.user_input %}{{ _endpoint.user_input }} {%- elif _endpoint.user_input %}{{ _endpoint.user_input }}

View file

@ -6,9 +6,10 @@
vars_files: vars_files:
- config.cfg - config.cfg
tasks: tasks:
- block: - name: Play server
block:
- name: Wait until the cloud-init completed - name: Wait until the cloud-init completed
wait_for: ansible.builtin.wait_for:
path: /var/lib/cloud/data/result.json path: /var/lib/cloud/data/result.json
delay: 10 delay: 10
timeout: 600 timeout: 600
@ -16,15 +17,19 @@
become: false become: false
when: cloudinit when: cloudinit
- block: - name: Not localhost
when: inventory_hostname != 'localhost'
become: false
delegate_to: localhost
block:
- name: Ensure the config directory exists - name: Ensure the config directory exists
file: ansible.builtin.file:
dest: configs/{{ IP_subject_alt_name }} dest: configs/{{ IP_subject_alt_name }}
state: directory state: directory
mode: "0700" mode: "0700"
- name: Dump the ssh config - name: Dump the ssh config
copy: ansible.builtin.copy:
dest: configs/{{ IP_subject_alt_name }}/ssh_config dest: configs/{{ IP_subject_alt_name }}/ssh_config
mode: "0600" mode: "0600"
content: | content: |
@ -35,38 +40,36 @@
IdentityFile {{ SSH_keys.private | realpath }} IdentityFile {{ SSH_keys.private | realpath }}
KeepAlive yes KeepAlive yes
ServerAliveInterval 30 ServerAliveInterval 30
when: inventory_hostname != 'localhost'
become: false
delegate_to: localhost
- import_role: - ansible.builtin.import_role:
name: common name: common
tags: common tags: common
- import_role: - ansible.builtin.import_role:
name: dns name: dns
when: when:
- algo_dns_adblocking or dns_encryption - algo_dns_adblocking or dns_encryption
tags: dns tags: dns
- import_role: - ansible.builtin.import_role:
name: wireguard name: wireguard
when: wireguard_enabled when: wireguard_enabled
tags: wireguard tags: wireguard
- import_role: - ansible.builtin.import_role:
name: strongswan name: strongswan
when: ipsec_enabled when: ipsec_enabled
tags: ipsec tags: ipsec
- import_role: - ansible.builtin.import_role:
name: ssh_tunneling name: ssh_tunneling
when: algo_ssh_tunneling when: algo_ssh_tunneling
tags: ssh_tunneling tags: ssh_tunneling
- block: - name: Set configuration
block:
- name: Dump the configuration - name: Dump the configuration
copy: ansible.builtin.copy:
dest: configs/{{ IP_subject_alt_name }}/.config.yml dest: configs/{{ IP_subject_alt_name }}/.config.yml
content: | content: |
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }} server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
@ -94,7 +97,7 @@
delegate_to: localhost delegate_to: localhost
- name: Create a symlink if deploying to localhost - name: Create a symlink if deploying to localhost
file: ansible.builtin.file:
src: "{{ IP_subject_alt_name }}" src: "{{ IP_subject_alt_name }}"
dest: configs/localhost dest: configs/localhost
state: link state: link
@ -102,7 +105,7 @@
when: inventory_hostname == 'localhost' when: inventory_hostname == 'localhost'
- name: Import tmpfs tasks - name: Import tmpfs tasks
import_tasks: playbooks/tmpfs/umount.yml ansible.builtin.import_tasks: tasks/tmpfs/umount.yml
become: false become: false
delegate_to: localhost delegate_to: localhost
vars: vars:
@ -111,7 +114,7 @@
- pki_in_tmpfs - pki_in_tmpfs
- not algo_store_pki - not algo_store_pki
- debug: - ansible.builtin.debug:
msg: msg:
- "{{ congrats.common.split('\n') }}" - "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}" - " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
@ -119,4 +122,4 @@
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}" - " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always tags: always
rescue: rescue:
- include_tasks: playbooks/rescue.yml - ansible.builtin.include_tasks: tasks/rescue.yml

View file

@ -1,10 +1,10 @@
--- ---
- name: Set subjectAltName as a fact - name: Set subjectAltName as a fact
set_fact: ansible.builtin.set_fact:
IP_subject_alt_name: "{{ (IP_subject_alt_name if algo_provider == 'local' else cloud_instance_ip) | lower }}" IP_subject_alt_name: "{{ (IP_subject_alt_name if algo_provider == 'local' else cloud_instance_ip) | lower }}"
- name: Add the server to an inventory group - name: Add the server to an inventory group
add_host: ansible.builtin.add_host:
name: "{% if cloud_instance_ip == 'localhost' %}localhost{% else %}{{ cloud_instance_ip }}{% endif %}" name: "{% if cloud_instance_ip == 'localhost' %}localhost{% else %}{{ cloud_instance_ip }}{% endif %}"
groups: vpn-host groups: vpn-host
ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}" ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}"
@ -24,13 +24,13 @@
cloudinit: "{{ cloudinit|default(false) }}" cloudinit: "{{ cloudinit|default(false) }}"
- name: Additional variables for the server - name: Additional variables for the server
add_host: ansible.builtin.add_host:
name: "{% if cloud_instance_ip == 'localhost' %}localhost{% else %}{{ cloud_instance_ip }}{% endif %}" name: "{% if cloud_instance_ip == 'localhost' %}localhost{% else %}{{ cloud_instance_ip }}{% endif %}"
ansible_ssh_private_key_file: "{{ SSH_keys.private_tmp }}" ansible_ssh_private_key_file: "{{ SSH_keys.private_tmp }}"
when: algo_provider != 'local' when: algo_provider != 'local'
- name: Wait until SSH becomes ready... - name: Wait until SSH becomes ready...
wait_for: ansible.builtin.wait_for:
port: "{{ ansible_ssh_port|default(22) }}" port: "{{ ansible_ssh_port|default(22) }}"
host: "{{ cloud_instance_ip }}" host: "{{ cloud_instance_ip }}"
search_regex: OpenSSH search_regex: OpenSSH
@ -40,16 +40,17 @@
when: cloud_instance_ip != "localhost" when: cloud_instance_ip != "localhost"
- name: Mount tmpfs - name: Mount tmpfs
import_tasks: tmpfs/main.yml ansible.builtin.import_tasks: tmpfs/main.yml
when: when:
- pki_in_tmpfs - pki_in_tmpfs
- not algo_store_pki - not algo_store_pki
- ansible_system == "Darwin" or ansible_system == "Linux" - ansible_system == "Darwin" or ansible_system == "Linux"
- debug: - name: Debug | var IP_subject_alt_name
ansible.builtin.debug:
var: IP_subject_alt_name var: IP_subject_alt_name
- name: Wait 600 seconds for target connection to become reachable/usable - name: Wait 600 seconds for target connection to become reachable/usable
wait_for_connection: ansible.builtin.wait_for_connection:
delegate_to: "{{ item }}" delegate_to: "{{ item }}"
loop: "{{ groups['vpn-host'] }}" loop: "{{ groups['vpn-host'] }}"

View file

@ -1,7 +1,8 @@
--- ---
- block: - name: cloud-pre
block:
- name: Display the invocation environment - name: Display the invocation environment
shell: > ansible.builtin.shell: >
./algo-showenv.sh \ ./algo-showenv.sh \
'algo_provider "{{ algo_provider }}"' \ 'algo_provider "{{ algo_provider }}"' \
{% if ipsec_enabled %} {% if ipsec_enabled %}
@ -17,7 +18,7 @@
tags: debug tags: debug
- name: Install the requirements - name: Install the requirements
pip: ansible.builtin.pip:
state: present state: present
name: name:
- pyOpenSSL>=0.15 - pyOpenSSL>=0.15
@ -28,26 +29,27 @@
delegate_to: localhost delegate_to: localhost
become: false become: false
- block: - name: Provider not local
when: algo_provider != "local"
block:
- name: Generate the SSH private key - name: Generate the SSH private key
openssl_privatekey: ansible.builtin.openssl_privatekey:
path: "{{ SSH_keys.private }}" path: "{{ SSH_keys.private }}"
size: 2048 size: 2048
mode: "0600" mode: "0600"
type: RSA type: RSA
- name: Generate the SSH public key - name: Generate the SSH public key
openssl_publickey: ansible.builtin.openssl_publickey:
path: "{{ SSH_keys.public }}" path: "{{ SSH_keys.public }}"
privatekey_path: "{{ SSH_keys.private }}" privatekey_path: "{{ SSH_keys.private }}"
format: OpenSSH format: OpenSSH
- name: Copy the private SSH key to /tmp - name: Copy the private SSH key to /tmp
copy: ansible.builtin.copy:
src: "{{ SSH_keys.private }}" src: "{{ SSH_keys.private }}"
dest: "{{ SSH_keys.private_tmp }}" dest: "{{ SSH_keys.private_tmp }}"
force: true force: true
mode: "0600" mode: "0600"
delegate_to: localhost delegate_to: localhost
become: false become: false
when: algo_provider != "local"

7
tasks/rescue.yml Normal file
View file

@ -0,0 +1,7 @@
---
- name: Debug | var fail_hint
ansible.builtin.debug:
var: fail_hint
- name: Fail the installation
ansible.builtin.fail:

View file

@ -1,14 +1,17 @@
--- ---
- hosts: localhost - name: Playbook users
hosts: localhost
gather_facts: false gather_facts: false
tags: always tags: always
vars_files: vars_files:
- config.cfg - config.cfg
tasks: tasks:
- block: - name: Var server undefined
when: server is undefined
block:
- name: Get list of installed config files - name: Get list of installed config files
find: ansible.builtin.find:
paths: configs/ paths: configs/
depth: 2 depth: 2
recurse: true recurse: true
@ -17,12 +20,12 @@
register: _configs_list register: _configs_list
- name: Verify servers - name: Verify servers
assert: ansible.builtin.assert:
that: _configs_list.matched > 0 that: _configs_list.matched > 0
msg: No servers found, nothing to update. msg: No servers found, nothing to update.
- name: Build list of installed servers - name: Build list of installed servers
set_fact: ansible.builtin.set_fact:
server_list: >- server_list: >-
[{% for i in _configs_list.files %} [{% for i in _configs_list.files %}
{% set config = lookup('file', i.path)|from_yaml %} {% set config = lookup('file', i.path)|from_yaml %}
@ -31,49 +34,50 @@
{% endfor %}] {% endfor %}]
- name: Server address prompt - name: Server address prompt
pause: ansible.builtin.pause:
prompt: | prompt: |
Select the server to update user list below: Select the server to update user list below:
{% for r in server_list %} {% for r in server_list %}
{{ loop.index }}. {{ r }} {{ loop.index }}. {{ r }}
{% endfor %} {% endfor %}
register: _server register: _server
when: server is undefined
- block: - name: Set variables
block:
- name: Set facts based on the input - name: Set facts based on the input
set_fact: ansible.builtin.set_fact:
algo_server: >- algo_server: >-
{% if server is defined %}{{ server }} {% if server is defined %}{{ server }}
{%- elif _server.user_input %}{{ server_list[_server.user_input | int -1 ] }} {%- elif _server.user_input %}{{ server_list[_server.user_input | int -1 ] }}
{%- else %}omit{% endif %} {%- else %}omit{% endif %}
- name: Import host specific variables - name: Import host specific variables
include_vars: ansible.builtin.include_vars:
file: configs/{{ algo_server }}/.config.yml file: configs/{{ algo_server }}/.config.yml
- when: ipsec_enabled - name: ipsec enabled
when: ipsec_enabled
block: block:
- name: CA password prompt - name: CA password prompt
pause: ansible.builtin.pause:
prompt: Enter the password for the private CA key prompt: Enter the password for the private CA key
echo: false echo: false
register: _ca_password register: _ca_password
when: ca_password is undefined when: ca_password is undefined
- name: Set facts based on the input - name: Set facts based on the input
set_fact: ansible.builtin.set_fact:
CA_password: >- CA_password: >-
{% if ca_password is defined %}{{ ca_password }} {% if ca_password is defined %}{{ ca_password }}
{%- elif _ca_password.user_input %}{{ _ca_password.user_input }} {%- elif _ca_password.user_input %}{{ _ca_password.user_input }}
{%- else %}omit{% endif %} {%- else %}omit{% endif %}
- name: Local pre-tasks - name: Local pre-tasks
import_tasks: playbooks/cloud-pre.yml ansible.builtin.import_tasks: tasks/cloud-pre.yml
become: false become: false
- name: Add the server to the vpn-host group - name: Add the server to the vpn-host group
add_host: ansible.builtin.add_host:
name: "{{ algo_server }}" name: "{{ algo_server }}"
groups: vpn-host groups: vpn-host
ansible_ssh_user: "{{ server_user|default('root') }}" ansible_ssh_user: "{{ server_user|default('root') }}"
@ -81,7 +85,7 @@
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3
CA_password: "{{ CA_password|default(omit) }}" CA_password: "{{ CA_password|default(omit) }}"
rescue: rescue:
- include_tasks: playbooks/rescue.yml - ansible.builtin.include_tasks: tasks/rescue.yml
- name: User management - name: User management
hosts: vpn-host hosts: vpn-host
@ -92,24 +96,25 @@
- configs/{{ inventory_hostname }}/.config.yml - configs/{{ inventory_hostname }}/.config.yml
tasks: tasks:
- block: - name: Play roles
- import_role: block:
- ansible.builtin.import_role:
name: common name: common
- import_role: - ansible.builtin.import_role:
name: wireguard name: wireguard
when: wireguard_enabled when: wireguard_enabled
- import_role: - ansible.builtin.import_role:
name: strongswan name: strongswan
when: ipsec_enabled when: ipsec_enabled
tags: ipsec tags: ipsec
- import_role: - ansible.builtin.import_role:
name: ssh_tunneling name: ssh_tunneling
when: algo_ssh_tunneling when: algo_ssh_tunneling
- debug: - ansible.builtin.debug:
msg: msg:
- "{{ congrats.common.split('\n') }}" - "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}" - " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
@ -117,4 +122,4 @@
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}" - " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always tags: always
rescue: rescue:
- include_tasks: playbooks/rescue.yml - ansible.builtin.include_tasks: playbooks/rescue.yml