This commit is contained in:
Julien 2023-10-01 12:38:07 -06:00 committed by GitHub
commit 675bd43e65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 522 additions and 405 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

@ -7,7 +7,7 @@
tasks:
- name: Add the droplet to an inventory group
add_host:
ansible.builtin.add_host:
name: "{{ client_ip }}"
groups: client-host
ansible_ssh_user: "{{ 'root' if client_ip == 'localhost' else ssh_user }}"

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: tasks/rescue.yml

View file

@ -1,28 +1,30 @@
---
- hosts: localhost
- name: Main playbook
hosts: localhost
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 +35,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 +43,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,3 +1,5 @@
---
- name: restart strongswan
service: name={{ strongswan_service }} state=restarted
- name: Restart strongswan
ansible.builtin.service:
name: "{{ strongswan_service }}"
state: restarted

View file

@ -1,11 +1,13 @@
---
- name: Gather Facts
setup:
ansible.builtin.setup:
- name: Include system based facts and tasks
import_tasks: systems/main.yml
ansible.builtin.import_tasks: systems/main.yml
- name: Install prerequisites
package: name="{{ item }}" state=present
ansible.builtin.package:
name: "{{ item }}"
state: present
with_items:
- "{{ prerequisites }}"
register: result
@ -14,34 +16,36 @@
delay: 3
- name: Install strongSwan
package: name=strongswan state=present
ansible.builtin.package:
name: strongswan
state: present
register: result
until: result is succeeded
retries: 10
delay: 3
- name: Setup the ipsec config
template:
ansible.builtin.template:
src: roles/strongswan/templates/client_ipsec.conf.j2
dest: "{{ configs_prefix }}/ipsec.{{ IP_subject_alt_name }}.conf"
mode: "0644"
with_items:
- "{{ vpn_user }}"
notify:
- restart strongswan
- Restart strongswan
- name: Setup the ipsec secrets
template:
ansible.builtin.template:
src: roles/strongswan/templates/client_ipsec.secrets.j2
dest: "{{ configs_prefix }}/ipsec.{{ IP_subject_alt_name }}.secrets"
mode: "0600"
with_items:
- "{{ vpn_user }}"
notify:
- restart strongswan
- Restart strongswan
- name: Include additional ipsec config
lineinfile:
ansible.builtin.lineinfile:
dest: "{{ item.dest }}"
line: "{{ item.line }}"
create: true
@ -51,26 +55,30 @@
- dest: "{{ configs_prefix }}/ipsec.secrets"
line: include ipsec.{{ IP_subject_alt_name }}.secrets
notify:
- restart strongswan
- Restart strongswan
- name: Configure libstrongswan to relax CA constraints
copy:
ansible.builtin.copy:
src: libstrongswan-relax-constraints.conf
dest: "{{ configs_prefix }}/strongswan.d/relax-ca-constraints.conf"
owner: root
group: root
mode: 0644
mode: "0644"
- name: Setup the certificates and keys
template:
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/certs/{{ vpn_user }}.crt
dest: "{{ configs_prefix }}/ipsec.d/certs/{{ vpn_user }}.crt"
mode: "0644"
- src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/cacert.pem
dest: "{{ configs_prefix }}/ipsec.d/cacerts/{{ IP_subject_alt_name }}.pem"
mode: "0644"
- src: configs/{{ IP_subject_alt_name }}/ipsec/.pki/private/{{ vpn_user }}.key
dest: "{{ configs_prefix }}/ipsec.d/private/{{ vpn_user }}.key"
mode: "0600"
notify:
- restart strongswan
- Restart strongswan

View file

@ -1,6 +1,6 @@
---
- name: Set OS specific facts
set_fact:
ansible.builtin.set_fact:
prerequisites:
- epel-release
configs_prefix: /etc/strongswan

View file

@ -1,6 +1,6 @@
---
- name: Set OS specific facts
set_fact:
ansible.builtin.set_fact:
prerequisites:
- libstrongswan-standard-plugins
configs_prefix: /etc

View file

@ -1,6 +1,6 @@
---
- name: Set OS specific facts
set_fact:
ansible.builtin.set_fact:
prerequisites:
- libselinux-python
configs_prefix: /etc/strongswan

View file

@ -1,6 +1,6 @@
---
- name: Set OS specific facts
set_fact:
ansible.builtin.set_fact:
prerequisites:
- libstrongswan-standard-plugins
configs_prefix: /etc

View file

@ -1,12 +1,16 @@
---
- include_tasks: Debian.yml
- name: Include Debian
ansible.builtin.include_tasks: Debian.yml
when: ansible_distribution == 'Debian'
- include_tasks: Ubuntu.yml
- name: Include Ubuntu
ansible.builtin.include_tasks: Ubuntu.yml
when: ansible_distribution == 'Ubuntu'
- include_tasks: CentOS.yml
- name: Include CentOS
ansible.builtin.include_tasks: CentOS.yml
when: ansible_distribution == 'CentOS'
- include_tasks: Fedora.yml
- name: Include Fedora
ansible.builtin.include_tasks: Fedora.yml
when: ansible_distribution == 'Fedora'

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,20 +1,20 @@
---
- name: Define facts
set_fact:
ansible.builtin.set_fact:
p12_export_password: "{{ p12_password|default(lookup('password', '/dev/null length=9 chars=ascii_letters,digits,_,@')) }}"
tags: update-users
- name: Set facts
set_fact:
ansible.builtin.set_fact:
CA_password: "{{ ca_password|default(lookup('password', '/dev/null length=16 chars=ascii_letters,digits,_,@')) }}"
IP_subject_alt_name: "{{ IP_subject_alt_name }}"
- name: Set IPv6 support as a fact
set_fact:
ansible.builtin.set_fact:
ipv6_support: "{% if ansible_default_ipv6['gateway'] is defined %}true{% else %}false{% endif %}"
tags: always
- name: Check size of MTU
set_fact:
ansible.builtin.set_fact:
reduce_mtu: "{{ 1500 - ansible_default_ipv4['mtu']|int if reduce_mtu|int == 0 and ansible_default_ipv4['mtu']|int < 1500 else reduce_mtu|int }}"
tags: always

View file

@ -1,6 +1,6 @@
---
- name: FreeBSD | Install prerequisites
package:
ansible.builtin.package:
name:
- python3
- sudo
@ -8,16 +8,16 @@
ansible_python_interpreter: /usr/local/bin/python2.7
- name: Set python3 as the interpreter to use
set_fact:
ansible.builtin.set_fact:
ansible_python_interpreter: /usr/local/bin/python3
- name: Gather facts
setup:
ansible.builtin.setup:
- name: Gather additional facts
import_tasks: facts.yml
ansible.builtin.import_tasks: facts.yml
- name: Set OS specific facts
set_fact:
ansible.builtin.set_fact:
config_prefix: /usr/local/
strongswan_shell: /usr/sbin/nologin
strongswan_home: /var/empty
@ -42,12 +42,14 @@
value: 1
- name: Install tools
package: name="{{ item }}" state=present
ansible.builtin.package:
name: "{{ item }}"
state: present
with_items:
- "{{ tools|default([]) }}"
- name: Loopback included into the rc config
blockinfile:
ansible.builtin.blockinfile:
dest: /etc/rc.conf
create: true
block: |
@ -58,7 +60,10 @@
- restart loopback bsd
- name: Enable the gateway features
lineinfile: dest=/etc/rc.conf regexp='^{{ item.param }}.*' line='{{ item.param }}={{ item.value }}'
ansible.builtin.lineinfile:
dest: /etc/rc.conf
regexp: '^{{ item.param }}.*'
line: '{{ item.param }}={{ item.value }}'
with_items:
- { param: firewall_enable, value: '"YES"' }
- { param: firewall_type, value: '"open"' }
@ -70,9 +75,10 @@
- restart ipfw
- name: FreeBSD | Activate IPFW
shell: >
ansible.builtin.shell: >
kldstat -n ipfw.ko || kldload ipfw ; sysctl net.inet.ip.fw.enable=0 &&
bash /etc/rc.firewall && sysctl net.inet.ip.fw.enable=1
changed_when: false
- meta: flush_handlers
- name: Flush handlers
ansible.builtin.meta: flush_handlers

View file

@ -1,23 +1,23 @@
---
- name: Iptables configured
template:
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: 0640
mode: "0640"
with_items:
- { src: rules.v4.j2, dest: /etc/iptables/rules.v4 }
notify:
- restart iptables
- name: Iptables configured
template:
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: root
group: root
mode: 0640
mode: "0640"
when: ipv6_support
with_items:
- { src: rules.v6.j2, dest: /etc/iptables/rules.v6 }

View file

@ -1,30 +1,35 @@
---
- name: Check the system
raw: uname -a
ansible.builtin.raw: uname -a
register: OS
changed_when: false
tags:
- update-users
- fail:
- name: Fail
ansible.builtin.fail:
when: cloud_test|default(false)|bool
- include_tasks: ubuntu.yml
- name: Include ubuntu
ansible.builtin.include_tasks: ubuntu.yml
when: '"Ubuntu" in OS.stdout or "Linux" in OS.stdout'
tags:
- update-users
- include_tasks: freebsd.yml
- name: Include freebsd
ansible.builtin.include_tasks: freebsd.yml
when: '"FreeBSD" in OS.stdout'
tags:
- update-users
- name: Sysctl tuning
sysctl: name="{{ item.item }}" value="{{ item.value }}"
ansible.posix.sysctl:
name: "{{ item.item }}"
value: "{{ item.value }}"
when: item.item
with_items:
- "{{ sysctl|default([]) }}"
tags:
- always
- meta: flush_handlers
- ansible.builtin.meta: flush_handlers

View file

@ -1,10 +1,10 @@
---
- name: Gather facts
setup:
ansible.builtin.setup:
- name: Cloud only tasks
block:
- name: Install software updates
apt:
ansible.builtin.apt:
update_cache: true
install_recommends: true
upgrade: dist
@ -14,21 +14,21 @@
delay: 10
- name: Check if reboot is required
shell: >
ansible.builtin.shell: >
if [[ -e /var/run/reboot-required ]]; then echo "required"; else echo "no"; fi
args:
executable: /bin/bash
register: reboot_required
- name: Reboot
shell: sleep 2 && shutdown -r now "Ansible updates triggered"
ansible.builtin.shell: sleep 2 && shutdown -r now "Ansible updates triggered"
async: 1
poll: 0
when: reboot_required is defined and reboot_required.stdout == 'required'
ignore_errors: true
- name: Wait until the server becomes ready...
wait_for_connection:
ansible.builtin.wait_for_connection:
delay: 20
timeout: 320
when: reboot_required is defined and reboot_required.stdout == 'required'
@ -36,16 +36,19 @@
when: algo_provider != "local"
- name: Include unattended upgrades configuration
import_tasks: unattended-upgrades.yml
ansible.builtin.import_tasks: unattended-upgrades.yml
- name: Disable MOTD on login and SSHD
replace: dest="{{ item.file }}" regexp="{{ item.regexp }}" replace="{{ item.line }}"
ansible.builtin.replace:
dest: "{{ item.file }}"
regexp: "{{ item.regexp }}"
replace: "{{ item.line }}"
with_items:
- { regexp: ^session.*optional.*pam_motd.so.*, line: "# MOTD DISABLED", file: /etc/pam.d/login }
- { regexp: ^session.*optional.*pam_motd.so.*, line: "# MOTD DISABLED", file: /etc/pam.d/sshd }
- name: Ensure fallback resolvers are set
ini_file:
community.general.ini_file:
path: /etc/systemd/resolved.conf
section: Resolve
option: FallbackDNS
@ -54,14 +57,14 @@
- restart systemd-resolved
- name: Loopback for services configured
template:
ansible.builtin.template:
src: 10-algo-lo100.network.j2
dest: /etc/systemd/network/10-algo-lo100.network
notify:
- restart systemd-networkd
- name: systemd services enabled and started
systemd:
ansible.builtin.systemd:
name: "{{ item }}"
state: started
enabled: true
@ -70,24 +73,24 @@
- systemd-networkd
- systemd-resolved
- meta: flush_handlers
- ansible.builtin.meta: flush_handlers
- name: Check apparmor support
command: apparmor_status
ansible.builtin.command: apparmor_status
ignore_errors: true
changed_when: false
register: apparmor_status
- name: Set fact if apparmor enabled
set_fact:
ansible.builtin.set_fact:
apparmor_enabled: true
when: '"profiles are in enforce mode" in apparmor_status.stdout'
- name: Gather additional facts
import_tasks: facts.yml
ansible.builtin.import_tasks: facts.yml
- name: Set OS specific facts
set_fact:
ansible.builtin.set_fact:
tools:
- git
- screen
@ -108,13 +111,13 @@
value: 1
- name: Install tools
apt:
ansible.builtin.apt:
name: "{{ tools|default([]) }}"
state: present
update_cache: true
- name: Install headers
apt:
ansible.builtin.apt:
name:
- linux-headers-generic
- linux-headers-{{ ansible_kernel }}
@ -122,8 +125,9 @@
when: install_headers | bool
- name: Configure the alternative ingress ip
include_tasks: aip/main.yml
ansible.builtin.include_tasks: aip/main.yml
when: alternative_ingress_ip
- include_tasks: iptables.yml
- name: Include iptables
ansible.builtin.include_tasks: iptables.yml
tags: iptables

View file

@ -1,21 +1,21 @@
---
- name: Install unattended-upgrades
apt:
ansible.builtin.apt:
name: unattended-upgrades
state: present
- name: Configure unattended-upgrades
template:
ansible.builtin.template:
src: 50unattended-upgrades.j2
dest: /etc/apt/apt.conf.d/50unattended-upgrades
owner: root
group: root
mode: 0644
mode: "0644"
- name: Periodic upgrades configured
template:
ansible.builtin.template:
src: 10periodic.j2
dest: /etc/apt/apt.conf.d/10periodic
owner: root
group: root
mode: 0644
mode: "0644"

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: |
@ -36,38 +41,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 }}
@ -95,7 +98,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
@ -103,7 +106,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:
@ -112,7 +115,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 '' }}"
@ -120,4 +123,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,10 @@
---
- block:
- name: cloud-pre
delegate_to: localhost
become: false
block:
- name: Display the invocation environment
shell: >
ansible.builtin.shell: >
./algo-showenv.sh \
'algo_provider "{{ algo_provider }}"' \
{% if ipsec_enabled %}
@ -17,7 +20,7 @@
tags: debug
- name: Install the requirements
pip:
ansible.builtin.pip:
state: present
name:
- pyOpenSSL>=0.15
@ -25,29 +28,28 @@
tags:
- always
- skip_ansible_lint
delegate_to: localhost
become: false
- block:
- name: Provider not local
when: algo_provider != "local"
block:
- name: Generate the SSH private key
openssl_privatekey:
community.crypto.openssl_privatekey:
path: "{{ SSH_keys.private }}"
size: 2048
mode: "0600"
type: RSA
- name: Generate the SSH public key
openssl_publickey:
community.crypto.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,5 +1,5 @@
---
- name: Linux | set OS specific facts
set_fact:
ansible.builtin.set_fact:
tmpfs_volume_name: AlgoVPN-{{ IP_subject_alt_name }}
tmpfs_volume_path: /dev/shm

View file

@ -1,11 +1,11 @@
---
- name: MacOS | set OS specific facts
set_fact:
ansible.builtin.set_fact:
tmpfs_volume_name: AlgoVPN-{{ IP_subject_alt_name }}
tmpfs_volume_path: /Volumes
- name: MacOS | mount a ram disk
shell: >
ansible.builtin.shell: >
/usr/sbin/diskutil info "/{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/" ||
/usr/sbin/diskutil erasevolume HFS+ "{{ tmpfs_volume_name }}" $(hdiutil attach -nomount ram://64000)
args:

View file

@ -1,17 +1,17 @@
---
- name: Include tasks for MacOS
import_tasks: macos.yml
ansible.builtin.import_tasks: macos.yml
when: ansible_system == "Darwin"
- name: Include tasks for Linux
import_tasks: linux.yml
ansible.builtin.import_tasks: linux.yml
when: ansible_system == "Linux"
- name: Set config paths as facts
set_fact:
ansible.builtin.set_fact:
ipsec_pki_path: /{{ tmpfs_volume_path }}/{{ tmpfs_volume_name }}/IPsec/
- name: Update config paths
add_host:
ansible.builtin.add_host:
name: "{{ 'localhost' if cloud_instance_ip == 'localhost' else cloud_instance_ip }}"
ipsec_pki_path: "{{ ipsec_pki_path }}"

View file

@ -1,19 +1,22 @@
---
- name: Linux | Delete the PKI directory
file:
ansible.builtin.file:
path: /{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/
state: absent
when: facts.ansible_system == "Linux"
- block:
- name: Darwin
when:
- facts.ansible_system == "Darwin"
block:
- name: MacOS | check fs the ramdisk exists
command: /usr/sbin/diskutil info "{{ facts.tmpfs_volume_name }}"
ansible.builtin.command: /usr/sbin/diskutil info "{{ facts.tmpfs_volume_name }}"
ignore_errors: true
changed_when: false
register: diskutil_info
- name: MacOS | unmount and eject the ram disk
shell: >
ansible.builtin.shell: >
/usr/sbin/diskutil umount force "/{{ facts.tmpfs_volume_path }}/{{ facts.tmpfs_volume_name }}/" &&
/usr/sbin/diskutil eject "{{ facts.tmpfs_volume_name }}"
changed_when: false
@ -22,5 +25,4 @@
until: result.rc == 0
retries: 5
delay: 3
when:
- facts.ansible_system == "Darwin"

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,30 @@
- configs/{{ inventory_hostname }}/.config.yml
tasks:
- block:
- import_role:
- name: Play roles
block:
- name: Import common
ansible.builtin.import_role:
name: common
- import_role:
- name: Import wireguard
ansible.builtin.import_role:
name: wireguard
when: wireguard_enabled
- import_role:
- name: Import strongswan
ansible.builtin.import_role:
name: strongswan
when: ipsec_enabled
tags: ipsec
- import_role:
- name: Import ssh_tunneling
ansible.builtin.import_role:
name: ssh_tunneling
when: algo_ssh_tunneling
- debug:
- name: End message
ansible.builtin.debug:
msg:
- "{{ congrats.common.split('\n') }}"
- " {{ congrats.p12_pass if algo_ssh_tunneling or ipsec_enabled else '' }}"
@ -117,4 +127,4 @@
- " {{ congrats.ssh_access if algo_provider != 'local' else ''}}"
tags: always
rescue:
- include_tasks: playbooks/rescue.yml
- ansible.builtin.include_tasks: playbooks/rescue.yml