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:
- yaml
- '204'
- package-latest
- jinja[spacing]
verbosity: 1
warn_list:
- no-changed-when
- no-handler
- fqcn-builtins
- var-spacing
- experimental
- var-naming[pattern]
- yaml[line-length]
# - 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
run: |
/snap/bin/shellcheck algo install.sh
[ -f requirements.yml ] && ansible-galaxy install -r requirements.yml
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:
runs-on: ubuntu-20.04

View file

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

View file

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

View file

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

View file

@ -3,26 +3,27 @@
become: false
tasks:
- name: Playbook dir stat
stat:
ansible.builtin.stat:
path: "{{ playbook_dir }}"
register: _playbook_dir
- name: Ensure Ansible is not being run in a world writable directory
assert:
ansible.builtin.assert:
that: _playbook_dir.stat.mode|int <= 775
msg: >
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
- name: Ensure the requirements installed
debug:
ansible.builtin.debug:
msg: "{{ '' | ipaddr }}"
ignore_errors: true
no_log: true
register: ipaddr
# FIXME! failing if another matching pattern in requirements.txt aka ansible-lint
- 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\"\
: \"\\g<ver>\" }') }}"
when: '"ansible" in item'
@ -33,7 +34,7 @@
register: pip_package_info
- 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', '>=')
msg: >
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
- name: Verify Ansible meets Algo VPN requirements
assert:
ansible.builtin.assert:
that:
- pip_package_info.packages.pip.ansible.0.version is version(required_ansible_version.ver, required_ansible_version.op)
- 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
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
import_tasks: venv.yml
ansible.builtin.import_tasks: venv.yml
- name: Include prompts
import_tasks: prompts.yml
ansible.builtin.import_tasks: prompts.yml
- set_fact:
- name: Set fact
ansible.builtin.set_fact:
algo_region: >-
{% if region is defined %}{{ region }}
{%- elif _algo_region.user_input %}{{ azure_regions[_algo_region.user_input | int -1 ]['name'] }}
{%- else %}{{ azure_regions[default_region | int - 1]['name'] }}{% endif %}
- name: Create AlgoVPN Server
azure_rm_deployment:
azure.azcollection.azure_rm_deployment:
state: present
deployment_name: "{{ algo_server_name }}"
template: "{{ lookup('file', role_path + '/files/deployment.json') }}"
@ -45,7 +46,8 @@
value: "{{ lookup('template', 'files/cloud-init/base.yml') | b64encode }}"
register: azure_rm_deployment
- set_fact:
- name: Set fact
ansible.builtin.set_fact:
cloud_instance_ip: "{{ azure_rm_deployment.deployment.outputs.publicIPAddresses.value }}"
ansible_ssh_user: algo
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) }}"
tenant: "{{ azure_tenant | default(lookup('env','AZURE_TENANT'), 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) }}"
- block:
- name: Prompts
when: region is undefined
block:
- name: Set the default region
set_fact:
ansible.builtin.set_fact:
default_region: >-
{% for r in azure_regions %}
{%- if r['name'] == "eastus" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
- name: Read region
ansible.builtin.pause:
prompt: |
What region should the server be located in?
{% for r in azure_regions %}
@ -23,4 +27,3 @@
Enter the number of your desired region
[{{ default_region }}]
register: _algo_region
when: region is undefined

View file

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

View file

@ -1,25 +1,31 @@
---
- name: Build python virtual environment
import_tasks: venv.yml
ansible.builtin.import_tasks: venv.yml
- name: Include prompts
import_tasks: prompts.yml
ansible.builtin.import_tasks: prompts.yml
- block:
- set_fact:
- name: Cloudstack
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: >-
{% 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'] }}
{%- else %}{{ cs_zones[default_zone | int - 1]['name'] }}{% endif %}
- name: Security group created
cs_securitygroup:
ngine_io.cloudstack.cs_securitygroup:
name: "{{ algo_server_name }}-security_group"
description: AlgoVPN security group
register: cs_security_group
- name: Security rules created
cs_securitygroup_rule:
ngine_io.cloudstack.cs_securitygroup_rule:
security_group: "{{ cs_security_group.name }}"
protocol: "{{ item.proto }}"
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 }
- name: Set facts
set_fact:
ansible.builtin.set_fact:
image_id: "{{ cloud_providers.cloudstack.image }}"
size: "{{ cloud_providers.cloudstack.size }}"
disk: "{{ cloud_providers.cloudstack.disk }}"
- name: Server created
cs_instance:
ngine_io.cloudstack.cs_instance:
name: "{{ algo_server_name }}"
root_disk_size: "{{ disk }}"
template: "{{ image_id }}"
@ -48,12 +54,9 @@
user_data: "{{ lookup('template', 'files/cloud-init/base.yml') }}"
register: cs_server
- set_fact:
- name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ cs_server.default_ip }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"
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:
- pause:
- name: Prompts
block:
- name: Read API key
ansible.builtin.pause:
prompt: |
Enter the API key (https://trailofbits.github.io/algo/cloud-cloudstack.html):
echo: false
@ -9,7 +11,8 @@
- cs_key is undefined
- lookup('env','CLOUDSTACK_KEY')|length <= 0
- pause:
- name: Read API secret
ansible.builtin.pause:
prompt: |
Enter the API ssecret (https://trailofbits.github.io/algo/cloud-cloudstack.html):
echo: false
@ -18,7 +21,8 @@
- cs_secret is undefined
- lookup('env','CLOUDSTACK_SECRET')|length <= 0
- pause:
- name: Read API endpoint
ansible.builtin.pause:
prompt: |
Enter the API endpoint (https://trailofbits.github.io/algo/cloud-cloudstack.html)
[https://api.exoscale.com/compute]
@ -27,14 +31,15 @@
- cs_url is undefined
- 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_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',\
\ true) }}"
- name: Get zones on cloud
cs_zone_info:
ngine_io.cloudstack.cs_zone_info:
register: _cs_zones
environment:
CLOUDSTACK_KEY: "{{ algo_cs_key }}"
@ -42,17 +47,18 @@
CLOUDSTACK_ENDPOINT: "{{ algo_cs_url }}"
- name: Extract zones from output
set_fact:
ansible.builtin.set_fact:
cs_zones: "{{ _cs_zones['zones'] | sort(attribute='name') }}"
- name: Set the default zone
set_fact:
ansible.builtin.set_fact:
default_zone: >-
{% for z in cs_zones %}
{%- if z['name'] == "ch-gva-2" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
- name: Read zone
ansible.builtin.pause:
prompt: |
What zone should the server be located in?
{% for z in cs_zones %}

View file

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

View file

@ -1,16 +1,16 @@
---
- name: Include prompts
import_tasks: prompts.yml
ansible.builtin.import_tasks: prompts.yml
- name: Upload the SSH key
digital_ocean_sshkey:
community.digitalocean.digital_ocean_sshkey:
oauth_token: "{{ algo_do_token }}"
name: "{{ SSH_keys.comment }}"
ssh_pub_key: "{{ lookup('file', '{{ SSH_keys.public }}') }}"
register: do_ssh_key
- name: Creating a droplet...
digital_ocean_droplet:
community.digitalocean.digital_ocean_droplet:
state: present
name: "{{ algo_server_name }}"
oauth_token: "{{ algo_do_token }}"
@ -27,23 +27,26 @@
register: digital_ocean_droplet
# 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) }}"
- block:
- name: Alternative ingress IP
when: alternative_ingress_ip
block:
- name: Create a Floating IP
digital_ocean_floating_ip:
community.digitalocean.digital_ocean_floating_ip:
state: present
oauth_token: "{{ algo_do_token }}"
droplet_id: "{{ droplet.id }}"
register: digital_ocean_floating_ip
- 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 }}"
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 }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"

View file

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

View file

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

View file

@ -1,12 +1,12 @@
---
- name: Build python virtual environment
import_tasks: venv.yml
ansible.builtin.import_tasks: venv.yml
- name: Include prompts
import_tasks: prompts.yml
ansible.builtin.import_tasks: prompts.yml
- name: Locate official AMI for region
ec2_ami_info:
amazon.aws.ec2_ami_info:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
owners: "{{ cloud_providers.ec2.image.owner }}"
@ -17,13 +17,14 @@
register: ami_search
- 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'] }}"
- 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 }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
---
- pause:
- name: Read access key ID
ansible.builtin.pause:
prompt: |
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)
@ -9,7 +10,8 @@
- aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
- pause:
- name: Read secret access key
ansible.builtin.pause:
prompt: |
Enter your AWS Secret Access Key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
echo: false
@ -18,30 +20,34 @@
- aws_secret_key is undefined
- 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) }}"
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
aws_region_info:
community.aws.aws_region_info:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
region: us-east-1
register: _aws_regions
- name: Set facts about the regions
set_fact:
ansible.builtin.set_fact:
aws_regions: "{{ _aws_regions.regions | sort(attribute='region_name') }}"
- name: Set the default region
set_fact:
ansible.builtin.set_fact:
default_region: >-
{% for r in aws_regions %}
{%- if r['region_name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
- name: Read region
ansible.builtin.pause:
prompt: |
What region should the server be located in?
(https://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region)
@ -52,28 +58,31 @@
Enter the number of your desired region
[{{ default_region }}]
register: _algo_region
when: region is undefined
- name: Set algo_region and stack_name facts
set_fact:
ansible.builtin.set_fact:
algo_region: >-
{% if region is defined %}{{ region }}
{%- 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 %}
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
ec2_eip_info:
amazon.aws.ec2_eip_info:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
region: "{{ algo_region }}"
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 }}"
- pause:
- name: Read Elastic IP
ansible.builtin.pause:
prompt: >-
What Elastic IP would you like to use?
{% for eip in available_eip_addresses %}
@ -83,6 +92,6 @@
Enter the number of your desired Elastic IP
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'] }}"
when: cloud_providers.ec2.use_existing_eip

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,14 +1,15 @@
---
- name: Build python virtual environment
import_tasks: venv.yml
ansible.builtin.import_tasks: venv.yml
- name: Include prompts
import_tasks: prompts.yml
ansible.builtin.import_tasks: prompts.yml
- 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 }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"

View file

@ -1,5 +1,6 @@
---
- pause:
- name: Read access key
ansible.builtin.pause:
prompt: |
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)
@ -9,7 +10,8 @@
- aws_access_key is undefined
- lookup('env','AWS_ACCESS_KEY_ID')|length <= 0
- pause:
- name: Read secret key
ansible.builtin.pause:
prompt: |
Enter your aws_secret_key (http://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)
echo: false
@ -18,30 +20,34 @@
- aws_secret_key is undefined
- 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) }}"
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
lightsail_region_facts:
community.aws.aws_region_info:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
region: us-east-1
register: _lightsail_regions
- name: Set facts about the regions
set_fact:
ansible.builtin.set_fact:
lightsail_regions: "{{ _lightsail_regions.data.regions | sort(attribute='name') }}"
- name: Set the default region
set_fact:
ansible.builtin.set_fact:
default_region: >-
{% for r in lightsail_regions %}
{%- if r['name'] == "us-east-1" %}{{ loop.index }}{% endif %}
{%- endfor %}
- pause:
- name: Read region
ansible.builtin.pause:
prompt: |
What region should the server be located in?
(https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)
@ -52,9 +58,9 @@
Enter the number of your desired region
[{{ default_region }}]
register: _algo_region
when: region is undefined
- set_fact:
- name: Set facts
ansible.builtin.set_fact:
stack_name: "{{ algo_server_name | replace('.', '-') }}"
algo_region: >-
{% if region is defined %}{{ region }}

View file

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

View file

@ -1,44 +1,19 @@
---
- name: Build python virtual environment
import_tasks: venv.yml
ansible.builtin.import_tasks: venv.yml
- name: Include prompts
import_tasks: prompts.yml
ansible.builtin.import_tasks: prompts.yml
- name: Set facts
set_fact:
ansible.builtin.set_fact:
stackscript: |
{{ lookup('template', 'files/cloud-init/base.sh') }}
mkdir -p /var/lib/cloud/data/ || true
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...
linode_v4:
community.general.linode_v4:
access_token: "{{ algo_linode_token }}"
label: "{{ algo_server_name }}"
state: present
@ -46,10 +21,12 @@
image: "{{ cloud_providers.linode.image }}"
type: "{{ cloud_providers.linode.type }}"
authorized_keys: "{{ public_key }}"
stackscript_id: "{{ _linode_stackscript.stackscript.id }}"
stackscript_data: |
{{ stackscript }}
register: _linode
- set_fact:
- name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ _linode.instance.ipv4[0] }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"

View file

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

View file

@ -1,6 +1,6 @@
---
- name: Install requirements
pip:
ansible.builtin.pip:
name:
- linode_api4
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)"
when: lookup('env', 'OS_AUTH_URL')|length <= 0
- name: Build python virtual environment
import_tasks: venv.yml
ansible.builtin.import_tasks: venv.yml
- name: Security group created
openstack.cloud.security_group:
@ -38,7 +39,7 @@
register: os_image
- name: Set image as a fact
set_fact:
ansible.builtin.set_fact:
image_id: "{{ item.id }}"
loop: "{{ os_image.openstack_image }}"
when:
@ -50,7 +51,7 @@
register: os_network
- name: Set the network as a fact
set_fact:
ansible.builtin.set_fact:
public_network_id: "{{ item.id }}"
when:
- item['router:external']|default(omit)
@ -59,7 +60,7 @@
with_items: "{{ os_network.openstack_networks }}"
- name: Set facts
set_fact:
ansible.builtin.set_fact:
flavor_id: "{{ (os_flavor.openstack_flavors | sort(attribute='ram'))[0]['id'] }}"
security_group_name: "{{ os_security_group['secgroup']['name'] }}"
@ -75,7 +76,8 @@
- net-id: "{{ public_network_id }}"
register: os_server
- set_fact:
- name: Set facts
ansible.builtin.set_fact:
cloud_instance_ip: "{{ os_server['openstack']['public_v4'] }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"

View file

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

View file

@ -1,19 +1,24 @@
---
- 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
scaleway_organization_info:
community.general.scaleway_organization_info:
api_token: "{{ algo_scaleway_token }}"
register: scaleway_org
- name: Get images
scaleway_image_info:
community.general.scaleway_image_info:
region: "{{ algo_region }}"
api_token: "{{ algo_scaleway_token }}"
register: scaleway_image
- name: Set cloud specific facts
set_fact:
ansible.builtin.set_fact:
organization_id: "{{ scaleway_org.scaleway_organization_info[0]['id'] }}"
images: >-
[{% for i in scaleway_image.scaleway_image_info -%}
@ -24,7 +29,8 @@
{%- endfor -%}]
- name: Create a server
scaleway_compute:
community.general.scaleway_compute:
api_token: "{{ algo_scaleway_token }}"
name: "{{ algo_server_name }}"
enable_ipv6: true
public_ip: dynamic
@ -41,7 +47,7 @@
register: scaleway_compute
- 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
method: PATCH
body: "{{ lookup('template', 'files/cloud-init/base.yml') }}"
@ -51,7 +57,8 @@
X-Auth-Token: "{{ algo_scaleway_token }}"
- name: Start the server
scaleway_compute:
community.general.scaleway_compute:
api_token: "{{ algo_scaleway_token }}"
name: "{{ algo_server_name }}"
enable_ipv6: true
public_ip: dynamic
@ -69,10 +76,9 @@
until: algo_instance.msg.public_ip
retries: 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 }}"
ansible_ssh_user: algo
ansible_ssh_port: "{{ ssh_port }}"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,9 +6,10 @@
vars_files:
- config.cfg
tasks:
- block:
- name: Play server
block:
- name: Wait until the cloud-init completed
wait_for:
ansible.builtin.wait_for:
path: /var/lib/cloud/data/result.json
delay: 10
timeout: 600
@ -16,15 +17,19 @@
become: false
when: cloudinit
- block:
- name: Not localhost
when: inventory_hostname != 'localhost'
become: false
delegate_to: localhost
block:
- name: Ensure the config directory exists
file:
ansible.builtin.file:
dest: configs/{{ IP_subject_alt_name }}
state: directory
mode: "0700"
- name: Dump the ssh config
copy:
ansible.builtin.copy:
dest: configs/{{ IP_subject_alt_name }}/ssh_config
mode: "0600"
content: |
@ -35,38 +40,36 @@
IdentityFile {{ SSH_keys.private | realpath }}
KeepAlive yes
ServerAliveInterval 30
when: inventory_hostname != 'localhost'
become: false
delegate_to: localhost
- import_role:
- ansible.builtin.import_role:
name: common
tags: common
- import_role:
- ansible.builtin.import_role:
name: dns
when:
- algo_dns_adblocking or dns_encryption
tags: dns
- import_role:
- ansible.builtin.import_role:
name: wireguard
when: wireguard_enabled
tags: wireguard
- import_role:
- ansible.builtin.import_role:
name: strongswan
when: ipsec_enabled
tags: ipsec
- import_role:
- ansible.builtin.import_role:
name: ssh_tunneling
when: algo_ssh_tunneling
tags: ssh_tunneling
- block:
- name: Set configuration
block:
- name: Dump the configuration
copy:
ansible.builtin.copy:
dest: configs/{{ IP_subject_alt_name }}/.config.yml
content: |
server: {{ 'localhost' if inventory_hostname == 'localhost' else inventory_hostname }}
@ -94,7 +97,7 @@
delegate_to: localhost
- name: Create a symlink if deploying to localhost
file:
ansible.builtin.file:
src: "{{ IP_subject_alt_name }}"
dest: configs/localhost
state: link
@ -102,7 +105,7 @@
when: inventory_hostname == 'localhost'
- name: Import tmpfs tasks
import_tasks: playbooks/tmpfs/umount.yml
ansible.builtin.import_tasks: tasks/tmpfs/umount.yml
become: false
delegate_to: localhost
vars:
@ -111,7 +114,7 @@
- pki_in_tmpfs
- not algo_store_pki
- debug:
- ansible.builtin.debug:
msg:
- "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
@ -119,4 +122,4 @@
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always
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
set_fact:
ansible.builtin.set_fact:
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
add_host:
ansible.builtin.add_host:
name: "{% if cloud_instance_ip == 'localhost' %}localhost{% else %}{{ cloud_instance_ip }}{% endif %}"
groups: vpn-host
ansible_connection: "{% if cloud_instance_ip == 'localhost' %}local{% else %}ssh{% endif %}"
@ -24,13 +24,13 @@
cloudinit: "{{ cloudinit|default(false) }}"
- name: Additional variables for the server
add_host:
ansible.builtin.add_host:
name: "{% if cloud_instance_ip == 'localhost' %}localhost{% else %}{{ cloud_instance_ip }}{% endif %}"
ansible_ssh_private_key_file: "{{ SSH_keys.private_tmp }}"
when: algo_provider != 'local'
- name: Wait until SSH becomes ready...
wait_for:
ansible.builtin.wait_for:
port: "{{ ansible_ssh_port|default(22) }}"
host: "{{ cloud_instance_ip }}"
search_regex: OpenSSH
@ -40,16 +40,17 @@
when: cloud_instance_ip != "localhost"
- name: Mount tmpfs
import_tasks: tmpfs/main.yml
ansible.builtin.import_tasks: tmpfs/main.yml
when:
- pki_in_tmpfs
- not algo_store_pki
- ansible_system == "Darwin" or ansible_system == "Linux"
- debug:
- name: Debug | var IP_subject_alt_name
ansible.builtin.debug:
var: IP_subject_alt_name
- name: Wait 600 seconds for target connection to become reachable/usable
wait_for_connection:
ansible.builtin.wait_for_connection:
delegate_to: "{{ item }}"
loop: "{{ groups['vpn-host'] }}"

View file

@ -1,7 +1,8 @@
---
- block:
- name: cloud-pre
block:
- name: Display the invocation environment
shell: >
ansible.builtin.shell: >
./algo-showenv.sh \
'algo_provider "{{ algo_provider }}"' \
{% if ipsec_enabled %}
@ -17,7 +18,7 @@
tags: debug
- name: Install the requirements
pip:
ansible.builtin.pip:
state: present
name:
- pyOpenSSL>=0.15
@ -28,26 +29,27 @@
delegate_to: localhost
become: false
- block:
- name: Provider not local
when: algo_provider != "local"
block:
- name: Generate the SSH private key
openssl_privatekey:
ansible.builtin.openssl_privatekey:
path: "{{ SSH_keys.private }}"
size: 2048
mode: "0600"
type: RSA
- name: Generate the SSH public key
openssl_publickey:
ansible.builtin.openssl_publickey:
path: "{{ SSH_keys.public }}"
privatekey_path: "{{ SSH_keys.private }}"
format: OpenSSH
- name: Copy the private SSH key to /tmp
copy:
ansible.builtin.copy:
src: "{{ SSH_keys.private }}"
dest: "{{ SSH_keys.private_tmp }}"
force: true
mode: "0600"
delegate_to: localhost
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
tags: always
vars_files:
- config.cfg
tasks:
- block:
- name: Var server undefined
when: server is undefined
block:
- name: Get list of installed config files
find:
ansible.builtin.find:
paths: configs/
depth: 2
recurse: true
@ -17,12 +20,12 @@
register: _configs_list
- name: Verify servers
assert:
ansible.builtin.assert:
that: _configs_list.matched > 0
msg: No servers found, nothing to update.
- name: Build list of installed servers
set_fact:
ansible.builtin.set_fact:
server_list: >-
[{% for i in _configs_list.files %}
{% set config = lookup('file', i.path)|from_yaml %}
@ -31,49 +34,50 @@
{% endfor %}]
- name: Server address prompt
pause:
ansible.builtin.pause:
prompt: |
Select the server to update user list below:
{% for r in server_list %}
{{ loop.index }}. {{ r }}
{% endfor %}
register: _server
when: server is undefined
- block:
- name: Set variables
block:
- name: Set facts based on the input
set_fact:
ansible.builtin.set_fact:
algo_server: >-
{% if server is defined %}{{ server }}
{%- elif _server.user_input %}{{ server_list[_server.user_input | int -1 ] }}
{%- else %}omit{% endif %}
- name: Import host specific variables
include_vars:
ansible.builtin.include_vars:
file: configs/{{ algo_server }}/.config.yml
- when: ipsec_enabled
- name: ipsec enabled
when: ipsec_enabled
block:
- name: CA password prompt
pause:
ansible.builtin.pause:
prompt: Enter the password for the private CA key
echo: false
register: _ca_password
when: ca_password is undefined
- name: Set facts based on the input
set_fact:
ansible.builtin.set_fact:
CA_password: >-
{% if ca_password is defined %}{{ ca_password }}
{%- elif _ca_password.user_input %}{{ _ca_password.user_input }}
{%- else %}omit{% endif %}
- name: Local pre-tasks
import_tasks: playbooks/cloud-pre.yml
ansible.builtin.import_tasks: tasks/cloud-pre.yml
become: false
- name: Add the server to the vpn-host group
add_host:
ansible.builtin.add_host:
name: "{{ algo_server }}"
groups: vpn-host
ansible_ssh_user: "{{ server_user|default('root') }}"
@ -81,7 +85,7 @@
ansible_python_interpreter: /usr/bin/python3
CA_password: "{{ CA_password|default(omit) }}"
rescue:
- include_tasks: playbooks/rescue.yml
- ansible.builtin.include_tasks: tasks/rescue.yml
- name: User management
hosts: vpn-host
@ -92,24 +96,25 @@
- configs/{{ inventory_hostname }}/.config.yml
tasks:
- block:
- import_role:
- name: Play roles
block:
- ansible.builtin.import_role:
name: common
- import_role:
- ansible.builtin.import_role:
name: wireguard
when: wireguard_enabled
- import_role:
- ansible.builtin.import_role:
name: strongswan
when: ipsec_enabled
tags: ipsec
- import_role:
- ansible.builtin.import_role:
name: ssh_tunneling
when: algo_ssh_tunneling
- debug:
- ansible.builtin.debug:
msg:
- "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
@ -117,4 +122,4 @@
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always
rescue:
- include_tasks: playbooks/rescue.yml
- ansible.builtin.include_tasks: playbooks/rescue.yml