generated from Appsilon/ansible-role-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
90d2fa2
commit 4c0344e
Showing
16 changed files
with
593 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
********************************************* | ||
Amazon Web Services driver installation guide | ||
********************************************* | ||
|
||
Requirements | ||
============ | ||
|
||
* An AWS credentials rc file | ||
|
||
Install | ||
======= | ||
|
||
Please refer to the `Virtual environment`_ documentation for installation best | ||
practices. If not using a virtual environment, please consider passing the | ||
widely recommended `'--user' flag`_ when invoking ``pip``. | ||
|
||
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ | ||
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site | ||
|
||
.. code-block:: bash | ||
$ pip install 'molecule-ec2' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
--- | ||
- name: Converge | ||
hosts: all | ||
become: true | ||
pre_tasks: | ||
- name: Include vars | ||
include_vars: "{{ playbook_dir }}/../../tests/vars/main.yml" | ||
tasks: | ||
- name: "Include ansible-python-install" | ||
include_role: | ||
name: "ansible-python-install" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,323 @@ | ||
--- | ||
- name: Create | ||
hosts: localhost | ||
connection: local | ||
gather_facts: false | ||
no_log: "{{ molecule_no_log }}" | ||
collections: | ||
- community.aws | ||
- community.crypto | ||
vars: | ||
# Run config handling | ||
default_run_id: "{{ lookup('password', '/dev/null chars=ascii_lowercase length=5') }}" | ||
default_run_config: | ||
run_id: "{{ default_run_id }}" | ||
|
||
run_config_path: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/run-config.yml" | ||
run_config_from_file: "{{ (lookup('file', run_config_path, errors='ignore') or '{}') | from_yaml }}" | ||
run_config: '{{ default_run_config | combine(run_config_from_file) }}' | ||
|
||
# Platform settings handling | ||
default_assign_public_ip: true | ||
default_aws_profile: "{{ lookup('env', 'AWS_PROFILE') }}" | ||
default_boot_wait_seconds: 120 | ||
default_instance_type: t3a.medium | ||
default_key_inject_method: cloud-init # valid values: [cloud-init, ec2] | ||
default_key_name: "molecule-{{ run_config.run_id }}" | ||
default_private_key_path: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/id_rsa" | ||
default_public_key_path: "{{ default_private_key_path }}.pub" | ||
default_ssh_user: ec2-user | ||
default_ssh_port: 22 | ||
default_user_data: '' | ||
|
||
default_security_group_name: "molecule-{{ run_config.run_id }}" | ||
default_security_group_description: Ephemeral security group for Molecule instances | ||
default_security_group_rules: | ||
- proto: tcp | ||
from_port: "{{ default_ssh_port }}" | ||
to_port: "{{ default_ssh_port }}" | ||
cidr_ip: "0.0.0.0/0" | ||
- proto: icmp | ||
from_port: 8 | ||
to_port: -1 | ||
cidr_ip: "0.0.0.0/0" | ||
default_security_group_rules_egress: | ||
- proto: -1 | ||
from_port: 0 | ||
to_port: 0 | ||
cidr_ip: "0.0.0.0/0" | ||
|
||
platform_defaults: | ||
assign_public_ip: "{{ default_assign_public_ip }}" | ||
aws_profile: "{{ default_aws_profile }}" | ||
boot_wait_seconds: "{{ default_boot_wait_seconds }}" | ||
instance_type: "{{ default_instance_type }}" | ||
key_inject_method: "{{ default_key_inject_method }}" | ||
key_name: "{{ default_key_name }}" | ||
private_key_path: "{{ default_private_key_path }}" | ||
public_key_path: "{{ default_public_key_path }}" | ||
security_group_name: "{{ default_security_group_name }}" | ||
security_group_description: "{{ default_security_group_description }}" | ||
security_group_rules: "{{ default_security_group_rules }}" | ||
security_group_rules_egress: "{{ default_security_group_rules_egress }}" | ||
ssh_user: "{{ default_ssh_user }}" | ||
ssh_port: "{{ default_ssh_port }}" | ||
cloud_config: {} | ||
image: "" | ||
image_name: "" | ||
image_owner: [self] | ||
name: "" | ||
region: "" | ||
security_groups: [] | ||
tags: {} | ||
volumes: [] | ||
vpc_id: "" | ||
vpc_subnet_id: "" | ||
|
||
# Merging defaults into a list of dicts is, it turns out, not straightforward | ||
platforms: >- | ||
{{ [platform_defaults | dict2items] | ||
| product(molecule_yml.platforms | map('dict2items') | list) | ||
| map('flatten', levels=1) | ||
| list | ||
| map('items2dict') | ||
| list }} | ||
pre_tasks: | ||
- name: Validate platform configurations | ||
assert: | ||
that: | ||
- platforms | length > 0 | ||
- platform.name is string and platform.name | length > 0 | ||
- platform.assign_public_ip is boolean | ||
- platform.aws_profile is string | ||
- platform.boot_wait_seconds is integer and platform.boot_wait_seconds >= 0 | ||
- platform.cloud_config is mapping | ||
- platform.image is string | ||
- platform.image_name is string | ||
- platform.image_owner is sequence or (platform.image_owner is string and platform.image_owner | length > 0) | ||
- platform.instance_type is string and platform.instance_type | length > 0 | ||
- platform.key_inject_method is in ["cloud-init", "ec2"] | ||
- platform.key_name is string and platform.key_name | length > 0 | ||
- platform.private_key_path is string and platform.private_key_path | length > 0 | ||
- platform.public_key_path is string and platform.public_key_path | length > 0 | ||
- platform.region is string | ||
- platform.security_group_name is string and platform.security_group_name | length > 0 | ||
- platform.security_group_description is string and platform.security_group_description | length > 0 | ||
- platform.security_group_rules is sequence | ||
- platform.security_group_rules_egress is sequence | ||
- platform.security_groups is sequence | ||
- platform.ssh_user is string and platform.ssh_user | length > 0 | ||
- platform.ssh_port is integer and platform.ssh_port in range(1, 65536) | ||
- platform.tags is mapping | ||
- platform.volumes is sequence | ||
- platform.vpc_id is string | ||
- platform.vpc_subnet_id is string and platform.vpc_subnet_id | length > 0 | ||
quiet: true | ||
loop: '{{ platforms }}' | ||
loop_control: | ||
loop_var: platform | ||
label: "{{ platform.name }}" | ||
tasks: | ||
- name: Write run config to file | ||
copy: | ||
dest: "{{ run_config_path }}" | ||
content: "{{ run_config | to_yaml }}" | ||
|
||
- name: Generate local key pairs | ||
openssh_keypair: | ||
path: "{{ item.private_key_path }}" | ||
type: rsa | ||
size: 2048 | ||
regenerate: never | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
label: "{{ item.name }}" | ||
register: local_keypairs | ||
|
||
- name: Look up EC2 AMI(s) by owner and name (if image not set) | ||
ec2_ami_info: | ||
owners: "{{ item.image_owner }}" | ||
filters: | ||
name: "{{ item.image_name }}" | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
label: "{{ item.name }}" | ||
when: not item.image | ||
register: ami_info | ||
|
||
- name: Look up subnets to determine VPCs (if needed) | ||
ec2_vpc_subnet_info: | ||
subnet_ids: "{{ item.vpc_subnet_id }}" | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
label: "{{ item.name }}" | ||
when: not item.vpc_id | ||
register: subnet_info | ||
|
||
- name: Validate discovered information | ||
assert: | ||
that: | ||
- platform.image or (ami_info.results[index].images | length > 0) | ||
- platform.vpc_id or (subnet_info.results[index].subnets | length > 0) | ||
quiet: true | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
loop_var: platform | ||
index_var: index | ||
label: "{{ platform.name }}" | ||
|
||
- name: Create ephemeral EC2 keys (if needed) | ||
ec2_key: | ||
profile: "{{ item.aws_profile | default(omit) }}" | ||
region: "{{ item.region | default(omit) }}" | ||
name: "{{ item.key_name }}" | ||
key_material: "{{ local_keypair.public_key }}" | ||
vars: | ||
local_keypair: "{{ local_keypairs.results[index] }}" | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
index_var: index | ||
label: "{{ item.name }}" | ||
when: item.key_inject_method == "ec2" | ||
register: ec2_keys | ||
|
||
- name: Create ephemeral security groups (if needed) | ||
ec2_group: | ||
profile: "{{ item.aws_profile | default(omit) }}" | ||
region: "{{ item.region | default(omit) }}" | ||
vpc_id: "{{ item.vpc_id or vpc_subnet.vpc_id }}" | ||
name: "{{ item.security_group_name }}" | ||
description: "{{ item.security_group_description }}" | ||
rules: "{{ item.security_group_rules }}" | ||
rules_egress: "{{ item.security_group_rules_egress }}" | ||
vars: | ||
vpc_subnet: "{{ subnet_info.results[index].subnets[0] }}" | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
index_var: index | ||
label: "{{ item.name }}" | ||
when: item.security_groups | length == 0 | ||
|
||
- name: Create ephemeral EC2 instance(s) | ||
ec2_instance: | ||
profile: "{{ item.aws_profile | default(omit) }}" | ||
region: "{{ item.region | default(omit) }}" | ||
filters: "{{ platform_filters }}" | ||
instance_type: "{{ item.instance_type }}" | ||
image_id: "{{ platform_image_id }}" | ||
vpc_subnet_id: "{{ item.vpc_subnet_id }}" | ||
security_groups: "{{ platform_security_groups }}" | ||
network: | ||
assign_public_ip: "{{ item.assign_public_ip }}" | ||
volumes: "{{ item.volumes }}" | ||
key_name: "{{ (item.key_inject_method == 'ec2') | ternary(item.key_name, omit) }}" | ||
tags: "{{ platform_tags }}" | ||
user_data: "{{ platform_user_data }}" | ||
wait: true | ||
vars: | ||
platform_security_groups: "{{ item.security_groups or [item.security_group_name] }}" | ||
platform_generated_image_id: "{{ (ami_info.results[index].images | sort(attribute='creation_date', reverse=True))[0].image_id }}" | ||
platform_image_id: "{{ item.image or platform_generated_image_id }}" | ||
|
||
platform_generated_cloud_config: | ||
users: | ||
- name: "{{ item.ssh_user }}" | ||
ssh_authorized_keys: | ||
- "{{ local_keypairs.results[index].public_key }}" | ||
sudo: "ALL=(ALL) NOPASSWD:ALL" | ||
platform_cloud_config: >- | ||
{{ (item.key_inject_method == 'cloud-init') | ||
| ternary((item.cloud_config | combine(platform_generated_cloud_config)), item.cloud_config) }} | ||
platform_user_data: |- | ||
#cloud-config | ||
{{ platform_cloud_config | to_yaml }} | ||
platform_generated_tags: | ||
instance: "{{ item.name }}" | ||
"molecule-run-id": "{{ run_config.run_id }}" | ||
platform_tags: "{{ (item.tags or {}) | combine(platform_generated_tags) }}" | ||
platform_filter_keys: "{{ platform_generated_tags.keys() | map('regex_replace', '^(.+)$', 'tag:\\1') }}" | ||
platform_filters: "{{ dict(platform_filter_keys | zip(platform_generated_tags.values())) }}" | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
index_var: index | ||
label: "{{ item.name }}" | ||
register: ec2_instances_async | ||
async: 7200 | ||
poll: 0 | ||
|
||
- block: | ||
- name: Wait for instance creation to complete | ||
async_status: | ||
jid: "{{ item.ansible_job_id }}" | ||
loop: "{{ ec2_instances_async.results }}" | ||
loop_control: | ||
index_var: index | ||
label: "{{ platforms[index].name }}" | ||
register: ec2_instances | ||
until: ec2_instances is finished | ||
retries: 300 | ||
|
||
- name: Wait for public IP | ||
ansible.builtin.pause: | ||
seconds: 120 | ||
|
||
- name: Collect instance configs | ||
set_fact: | ||
instance_config: | ||
instance: "{{ item.name }}" | ||
address: "{{ item.assign_public_ip | ternary(instance.public_ip_address, instance.private_ip_address) }}" | ||
user: "{{ item.ssh_user }}" | ||
port: "{{ item.ssh_port }}" | ||
identity_file: "{{ item.private_key_path }}" | ||
instance_ids: | ||
- "{{ instance.instance_id }}" | ||
vars: | ||
instance: "{{ ec2_instances.results[index].instances[0] }}" | ||
loop: "{{ platforms }}" | ||
loop_control: | ||
index_var: index | ||
label: "{{ item.name }}" | ||
register: instance_configs | ||
|
||
- name: Write Molecule instance configs | ||
copy: | ||
dest: "{{ molecule_instance_config }}" | ||
content: >- | ||
{{ instance_configs.results | ||
| map(attribute='ansible_facts.instance_config') | ||
| list | ||
| to_json | ||
| from_json | ||
| to_yaml }} | ||
- name: Start SSH pollers | ||
wait_for: | ||
host: "{{ item.address }}" | ||
port: "{{ item.port }}" | ||
search_regex: SSH | ||
delay: 10 | ||
timeout: 320 | ||
loop: "{{ instance_configs.results | map(attribute='ansible_facts.instance_config') | list }}" | ||
loop_control: | ||
label: "{{ item.instance }}" | ||
register: ssh_wait_async | ||
async: 300 | ||
poll: 0 | ||
|
||
- name: Wait for SSH | ||
async_status: | ||
jid: "{{ item.ansible_job_id }}" | ||
loop: "{{ ssh_wait_async.results }}" | ||
loop_control: | ||
index_var: index | ||
label: "{{ platforms[index].name }}" | ||
register: ssh_wait | ||
until: ssh_wait_async is finished | ||
retries: 300 | ||
delay: 1 | ||
|
||
- name: Wait for boot process to finish | ||
pause: | ||
seconds: "{{ platforms | map(attribute='boot_wait_seconds') | max }}" | ||
when: ec2_instances_async is changed |
Oops, something went wrong.