diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 5478cd85..2ce030de 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -1,6 +1,6 @@ -name: changelog +name: Changelog concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 00000000..b6a7d5f9 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,59 @@ +name: Integration +on: + pull_request_target: + +jobs: + test: + runs-on: ubuntu-latest + env: + source: "./source" + aws_dir: "./amazon_aws" + ansible_version: "stable-2.14" + python_version: "3.9" + steps: + - name: Checkout collection + uses: actions/checkout@v3 + with: + path: ${{ env.source }} + + - name: Build and install collection + id: install-collection + uses: ansible-network/github_actions/.github/actions/build_install_collection@main + with: + install_python_dependencies: false + source_path: ${{ env.source }} + + - name: checkout ansible-collections/amazon.aws + uses: ansible-network/github_actions/.github/actions/checkout_dependency@main + with: + repository: ansible-collections/amazon.aws + path: ${{ env.amazon_aws }} + ref: main + + - name: install amazon.aws collection + uses: ansible-network/github_actions/.github/actions/build_install_collection@main + with: + install_python_dependencies: true + source_path: ${{ env.amazon_aws }} + + - name: Create AWS/sts session credentials + uses: ansible-network/github_actions/.github/actions/ansible_aws_test_provider@main + with: + collection_path: ${{ steps.install-collection.outputs.collection_path }} + ansible_core_ci_key: ${{ secrets.ANSIBLE_CORE_CI_KEY }} + + # we use raw git to create a repository in the tests + # this fails if the committer doesn't have a name and an email set + - name: Set up git + run: | + git config --global user.email gha@localhost + git config --global user.name "Github Actions" + shell: bash + + - name: Run integration tests + uses: ansible-network/github_actions/.github/actions/ansible_test_integration@main + with: + collection_path: ${{ steps.install-collection.outputs.collection_path }} + python_version: ${{ env.python_version }} + ansible_version: ${{ env.ansible_version }} + ansible_test_requirement_files: '' diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 31388fc4..8df6662a 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -1,35 +1,20 @@ --- name: Linters +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + 'on': push: - branches: - - main pull_request: - branches: - - main jobs: - linters: + uses: ansible-network/github_actions/.github/workflows/tox-linters.yml@main + ansible-lint: runs-on: ubuntu-latest - strategy: - matrix: - python_version: ['3.8'] steps: - - name: Check out code - uses: actions/checkout@v2 + - uses: ansible-network/github_actions/.github/actions/checkout_dependency@main - - name: Set up Python ${{ matrix.python_version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python_version }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox - - name: Test with tox - run: tox -e linters -vv - - ansible-lint: - uses: ansible-network/github_actions/.github/workflows/ansible-lint.yml@main + - name: Run ansible-lint + uses: ansible/ansible-lint-action@v6.16.0 diff --git a/.github/workflows/sanity.yml b/.github/workflows/sanity.yml index 02af4d6c..8bf8a5b1 100644 --- a/.github/workflows/sanity.yml +++ b/.github/workflows/sanity.yml @@ -1,17 +1,10 @@ -name: sanity +name: Sanity concurrency: - group: ${{ github.head_ref }} + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: pull_request: - types: - - opened - - reopened - - labeled - - unlabeled - - synchronize - - closed branches: - main - stable-* diff --git a/changelogs/fragments/ansible_lint_updates.yml b/changelogs/fragments/ansible_lint_updates.yml new file mode 100644 index 00000000..83547273 --- /dev/null +++ b/changelogs/fragments/ansible_lint_updates.yml @@ -0,0 +1,5 @@ +--- +trivial: + - "Add integration test workflow to GHA and add new integration tests targets (https://github.com/redhat-cop/cloud.aws_ops/pull/39)." +breaking_changes: + - role/aws_setup_credentials - Due to ansible-lint issue, the AWS generated credentials are now stored into variable `aws_setup_credentials__output` instead of `aws_role_credentials` (https://github.com/redhat-cop/cloud.aws_ops/pull/39)." diff --git a/roles/aws_setup_credentials/README.md b/roles/aws_setup_credentials/README.md index 60fc9219..22419597 100644 --- a/roles/aws_setup_credentials/README.md +++ b/roles/aws_setup_credentials/README.md @@ -1,71 +1,66 @@ -aws_setup_credentials -================== +# aws_setup_credentials -A role to define credentials for aws modules. The role defines a variable named **aws_role_credentials** which contains AWS credentials for Amazon modules based on user input. +A role to define credentials for aws modules. The role defines a variable named **aws_setup_credentials\_\_output** which contains AWS credentials for Amazon modules based on user input. -Requirements ------------- +## Requirements N/A -Role Variables --------------- - -* **aws_endpoint_url**: - - URL to use to connect to EC2 or your Eucalyptus cloud (by default the module will use EC2 endpoints). Ignored for modules where region is required. Must be specified for all other modules if region is not used. - - Environment variable: - - EC2_URL - - AWS_URL -* **aws_access_key**: - - The AWS access key to use. - - Mutually exclusive with option aws_profile. - - Environment variable: - - AWS_ACCESS_KEY_ID - - AWS_ACCESS_KEY - - EC2_ACCESS_KEY. -* **aws_secret_key**: - - The AWS secret key that corresponds to the access key. - - Mutually exclusive with option aws_profile. - - Environment variable: - - AWS_SECRET_ACCESS_KEY - - AWS_SECRET_KEY - - EC2_SECRET_KEY. -* **aws_security_token**: - - The AWS security token if using temporary access and secret keys. - - Mutually exclusive with option aws_profile. - - Environment variable: - - AWS_SECURITY_TOKEN - - EC2_SECURITY_TOKEN -* **aws_ca_bundle**: - - The location of a CA Bundle to use when validating SSL certificates. - - Environment variable: - - AWS_CA_BUNDLE -* **aws_validate_certs**: - - When set to "false", SSL certificates will not be validated for communication with the AWS APIs. - - Environment variable: - - AWS_VALIDATE_CERTS -* **aws_profile**: - - The AWS profile to use. - - Mutually exclusive with the aws_access_key, aws_secret_key and aws_security_token options. - - Environment variable: - - AWS_PROFILE - - AWS_DEFAULT_PROFILE. -* **aws_config**: - - A dictionary to modify the botocore configuration. - - Parameters can be found at [botocore config](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html#botocore.config.Config). -* **aws_region**: - - The AWS region to use. - - Environment variable: - - AWS_REGION - - EC2_REGION. - -Dependencies ------------- +## Role Variables + +- **aws_endpoint_url**: + - URL to use to connect to EC2 or your Eucalyptus cloud (by default the module will use EC2 endpoints). Ignored for modules where region is required. Must be specified for all other modules if region is not used. + - Environment variable: + - EC2_URL + - AWS_URL +- **aws_access_key**: + - The AWS access key to use. + - Mutually exclusive with option aws_profile. + - Environment variable: + - AWS_ACCESS_KEY_ID + - AWS_ACCESS_KEY + - EC2_ACCESS_KEY. +- **aws_secret_key**: + - The AWS secret key that corresponds to the access key. + - Mutually exclusive with option aws_profile. + - Environment variable: + - AWS_SECRET_ACCESS_KEY + - AWS_SECRET_KEY + - EC2_SECRET_KEY. +- **aws_security_token**: + - The AWS security token if using temporary access and secret keys. + - Mutually exclusive with option aws_profile. + - Environment variable: + - AWS_SECURITY_TOKEN + - EC2_SECURITY_TOKEN +- **aws_ca_bundle**: + - The location of a CA Bundle to use when validating SSL certificates. + - Environment variable: + - AWS_CA_BUNDLE +- **aws_validate_certs**: + - When set to "false", SSL certificates will not be validated for communication with the AWS APIs. + - Environment variable: + - AWS_VALIDATE_CERTS +- **aws_profile**: + - The AWS profile to use. + - Mutually exclusive with the aws_access_key, aws_secret_key and aws_security_token options. + - Environment variable: + - AWS_PROFILE + - AWS_DEFAULT_PROFILE. +- **aws_config**: + - A dictionary to modify the botocore configuration. + - Parameters can be found at [botocore config](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html#botocore.config.Config). +- **aws_region**: + - The AWS region to use. + - Environment variable: + - AWS_REGION + - EC2_REGION. + +## Dependencies - NA -Example Playbook ----------------- +## Example Playbook - hosts: localhost @@ -82,16 +77,14 @@ Example Playbook zone-name: eu-east-1 module_defaults: group/aws: - '{{ aws_role_credentials }}' + '{{ aws_setup_credentials__output }}' -License -------- +## License GNU General Public License v3.0 or later See [LICENCE](https://github.com/ansible-collections/cloud.aws_troubleshooting/blob/main/LICENSE) to see the full text. -Author Information ------------------- +## Author Information - Ansible Cloud Content Team diff --git a/roles/aws_setup_credentials/tasks/main.yml b/roles/aws_setup_credentials/tasks/main.yml index da0ee15e..8a6ae74f 100644 --- a/roles/aws_setup_credentials/tasks/main.yml +++ b/roles/aws_setup_credentials/tasks/main.yml @@ -1,7 +1,8 @@ --- - name: Define intial value for credentials ansible.builtin.set_fact: - aws_role_credentials: {} + aws_setup_credentials__output: {} + - name: Create auth credentials ansible.builtin.include_tasks: read_option.yml with_dict: "{{ aws_connection_env }}" diff --git a/roles/aws_setup_credentials/tasks/read_option.yml b/roles/aws_setup_credentials/tasks/read_option.yml index ef2f3e2c..f5fb4908 100644 --- a/roles/aws_setup_credentials/tasks/read_option.yml +++ b/roles/aws_setup_credentials/tasks/read_option.yml @@ -1,31 +1,30 @@ --- -- name: Set 'option_key' and 'option_value' from Environment +- name: Define key and value variables to search into environment ansible.builtin.set_fact: - option_key: "{{ ('dest' in item.value) | ternary(item.value.dest, item.key) }}" - option_value: "{{ lookup('vars', item.key, default='') }}" + aws_setup_credentials__item_key: "{{ ('dest' in item.value) | ternary(item.value.dest, item.key) }}" + aws_setup_credentials__item_value: "{{ lookup('vars', item.key, default='') }}" - name: Combine user-defined variable ansible.builtin.set_fact: - aws_role_credentials: "{{ aws_role_credentials | combine({option_key: option_value}) }}" - when: option_value | length > 0 + aws_setup_credentials__output: "{{ aws_setup_credentials__output | combine({aws_setup_credentials__item_key: aws_setup_credentials__item_value}) }}" + when: aws_setup_credentials__item_value | length > 0 - name: Read value from Environment - when: option_value | length == 0 + when: aws_setup_credentials__item_value | length == 0 block: - - name: Set 'env_values' variable + - name: Initialize environment variable list ansible.builtin.set_fact: - env_values: [] - - name: Set 'env_values' from Environment + aws_setup_credentials__env_values: [] + + - name: Append single environment variable into variables list ansible.builtin.set_fact: - env_values: "{{ env_values + [current_value] }}" + aws_setup_credentials__env_values: "{{ aws_setup_credentials__env_values + [lookup('env', aws_setup_credentials__env_key)] }}" with_items: "{{ ('env' in item.value) | ternary(item.value.env, []) }}" - when: current_value | length > 0 + when: lookup('env', aws_setup_credentials__env_key) | length > 0 loop_control: - loop_var: env_var - vars: - current_value: "{{ lookup('env', env_var) }}" + loop_var: aws_setup_credentials__env_key - name: Combine with environment-defined variable ansible.builtin.set_fact: - aws_role_credentials: "{{ aws_role_credentials | combine({option_key: env_values[0]}) }}" - when: env_values | length > 0 + aws_setup_credentials__output: "{{ aws_setup_credentials__output | combine({aws_setup_credentials__item_key: aws_setup_credentials__env_values[0]}) }}" + when: aws_setup_credentials__env_values | length > 0 diff --git a/roles/awsconfig_detach_and_delete_internet_gateway/tasks/main.yml b/roles/awsconfig_detach_and_delete_internet_gateway/tasks/main.yml index 208c9834..4e9edb1e 100644 --- a/roles/awsconfig_detach_and_delete_internet_gateway/tasks/main.yml +++ b/roles/awsconfig_detach_and_delete_internet_gateway/tasks/main.yml @@ -6,7 +6,7 @@ - name: Run 'awsconfig_detach_and_delete_internet_gateway' role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: # Wait for Internet Gateway Id being available @@ -14,49 +14,49 @@ amazon.aws.ec2_vpc_igw_info: internet_gateway_ids: - "{{ internet_gateway_id }}" - register: result + register: awsconfig_detach_and_delete_internet_gateway__info retries: 30 delay: 5 until: - - '"internet_gateways" in result' - - result.internet_gateways | length > 0 - - result.internet_gateways.0.attachments | map(attribute='state') | list | unique == ['available'] + - '"internet_gateways" in awsconfig_detach_and_delete_internet_gateway__info' + - awsconfig_detach_and_delete_internet_gateway__info.internet_gateways | length > 0 + - awsconfig_detach_and_delete_internet_gateway__info.internet_gateways.0.attachments | map(attribute='state') | list | unique == ['available'] ignore_errors: true - name: Fail when internet gateway does not exist ansible.builtin.fail: - msg: "{{ result.msg }}" - when: '"internet_gateways" not in result' + msg: "{{ awsconfig_detach_and_delete_internet_gateway__info.msg }}" + when: '"internet_gateways" not in awsconfig_detach_and_delete_internet_gateway__info' - name: Fail when internet gateway is not available ansible.builtin.fail: - msg: "Internet gateway not available: {{ result.internet_gateways.0.attachments }}" - when: result is failed + msg: "Internet gateway not available: {{ awsconfig_detach_and_delete_internet_gateway__info.internet_gateways.0.attachments }}" + when: awsconfig_detach_and_delete_internet_gateway__info is failed # Retrieves a specified virtual private gateway configuration. - name: Detach and delete Internet Gateway from VPC amazon.aws.ec2_vpc_igw: - vpc_id: "{{ result.internet_gateways.0.attachments.0.vpc_id }}" + vpc_id: "{{ awsconfig_detach_and_delete_internet_gateway__info.internet_gateways.0.attachments.0.vpc_id }}" state: absent ignore_errors: true - register: detach + register: awsconfig_detach_and_delete_internet_gateway__detach - name: Fail when when there are still public address(es) mapped ansible.builtin.fail: msg: >- - Some Amazon EC2 instances in your virtual private cloud ({{ result.internet_gateways.0.attachments.0.vpc_id }}) + Some Amazon EC2 instances in your virtual private cloud ({{ awsconfig_detach_and_delete_internet_gateway__info.internet_gateways.0.attachments.0.vpc_id }}) have elastic IP addresses or public IPv4 addresses associated with them, Please unmap those public address(es) before detaching the gateway. when: - - detach is failed - - '"error" in detach' - - detach.error.code == "DependencyViolation" - - '"has some mapped public address(es)" in detach.error.message' + - awsconfig_detach_and_delete_internet_gateway__detach is failed + - '"error" in awsconfig_detach_and_delete_internet_gateway__detach' + - awsconfig_detach_and_delete_internet_gateway__detach.error.code == "DependencyViolation" + - '"has some mapped public address(es)" in awsconfig_detach_and_delete_internet_gateway__detach.error.message' - - name: Fail when detach is failed + - name: Fail when module failed to detach internet gateway ansible.builtin.fail: - msg: "{{ detach.msg }}" - when: detach is failed + msg: "{{ awsconfig_detach_and_delete_internet_gateway__detach.msg }}" + when: awsconfig_detach_and_delete_internet_gateway__detach is failed - name: Internet Gateway has been detached from VPC and successfully deleted ansible.builtin.debug: diff --git a/roles/awsconfig_multiregion_cloudtrail/tasks/main.yml b/roles/awsconfig_multiregion_cloudtrail/tasks/main.yml index 1b06b8ec..66198099 100644 --- a/roles/awsconfig_multiregion_cloudtrail/tasks/main.yml +++ b/roles/awsconfig_multiregion_cloudtrail/tasks/main.yml @@ -18,7 +18,7 @@ - name: Run 'awsconfig_multiregion_cloudtrail' role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: - name: Create Cloud trail and start logging or Delete existing Cloud trail @@ -29,7 +29,7 @@ s3_bucket_name: "{{ bucket_name | default(omit) }}" s3_key_prefix: "{{ key_prefix | default(omit) }}" is_multi_region_trail: true - register: result + register: awsconfig_multiregion_cloudtrail_result - name: Create/update trail when: operation == 'create' @@ -37,12 +37,12 @@ - name: Verify that trail has been created/updated ansible.builtin.debug: msg: Trail '{{ trail_name }}' successfully created/updated. - when: result is changed + when: awsconfig_multiregion_cloudtrail_result is changed - name: Verify that trail already exists ansible.builtin.debug: msg: Trail '{{ trail_name }}' already exists. - when: result is not changed + when: awsconfig_multiregion_cloudtrail_result is not changed - name: Delete trail when: operation == 'delete' @@ -50,9 +50,9 @@ - name: Verify that trail has been deleted ansible.builtin.debug: msg: Trail '{{ trail_name }}' successfully deleted. - when: result is changed + when: awsconfig_multiregion_cloudtrail_result is changed - name: Verify that trail does not exists anymore ansible.builtin.debug: msg: Trail '{{ trail_name }}' does not exist. - when: not result.changed + when: awsconfig_multiregion_cloudtrail_result is not changed diff --git a/roles/customized_ami/defaults/main.yml b/roles/customized_ami/defaults/main.yml index cf382210..c7903459 100644 --- a/roles/customized_ami/defaults/main.yml +++ b/roles/customized_ami/defaults/main.yml @@ -4,12 +4,23 @@ source_ami_filters: architecture: x86_64 virtualization-type: hvm root-device-type: ebs - name: Fedora-Cloud-Base-35-* -source_ami_user_name: ec2-user + name: Fedora-Cloud-Base-37-* +source_ami_user_name: fedora custom_ami_vpc_cidr: 10.1.0.0/16 custom_ami_subnet_cidr: 10.1.0.0/24 custom_ami_ec2_instance_name: "{{ custom_ami_name }}-ec2" custom_ami_ec2_instance_type: t2.large +custom_ami_resource_tags: + role: customized_ami + customized_ami_name: "{{ custom_ami_name }}" + +custom_ami_vpc_name: "vpc-{{ custom_ami_name }}" +custom_ami_security_group: "security-{{ custom_ami_name }}" +custom_ami_key_name: "key-{{ custom_ami_name }}" +custom_ami_public_key_file: ~/.ssh/id_rsa.pub +custom_ami_private_key_file: ~/.ssh/id_rsa +custom_ami_security_group_desc: "Security group allowing SSH connection to EC2 instance" + custom_ami_recreate_if_exists: false diff --git a/roles/customized_ami/meta/main.yml b/roles/customized_ami/meta/main.yml new file mode 100644 index 00000000..e8b3ab42 --- /dev/null +++ b/roles/customized_ami/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: cloud.aws_ops.aws_setup_credentials diff --git a/roles/customized_ami/tasks/create.yaml b/roles/customized_ami/tasks/create.yaml index 6ada5ace..687c014d 100644 --- a/roles/customized_ami/tasks/create.yaml +++ b/roles/customized_ami/tasks/create.yaml @@ -1,87 +1,25 @@ --- -- name: Check if the AMI already exists - amazon.aws.ec2_ami_info: - filters: - name: "{{ custom_ami_name }}" - register: existing +- name: Delete existing images + ansible.builtin.include_tasks: delete.yaml - name: Create custom AMI - when: (existing.images | length == 0) or (custom_ami_recreate_if_exists | bool) block: - - name: Delete existing AMI - amazon.aws.ec2_ami: - name: "{{ existing.images.0.name }}" - image_id: "{{ existing.images.0.image_id }}" - wait: true - state: absent - when: existing.images | length > 0 + - name: Get Source AMI identifier + ansible.builtin.include_tasks: read_source_ami.yaml - - name: Get source AMI id - when: source_ami_image_id is not defined - block: - - name: Get source AMI image ID using filters - amazon.aws.ec2_ami_info: - filters: "{{ source_ami_filters }}" - register: images - # very spammy - no_log: true + - name: Get Source AMI identifier + ansible.builtin.include_tasks: create_ec2_resources.yaml - - name: Fail when no AMI found using filters - ansible.builtin.fail: - msg: No AMI found using filters - when: images.images | length == 0 + - name: Create custom AMI + ansible.builtin.include_tasks: create_ami.yaml - - name: Define AMI id to create EC2 instance - ansible.builtin.set_fact: - source_ami_image_id: "{{ source_ami_image_id is defined | ternary(source_ami_image_id, images.images.0.image_id) }}" - - - name: Set 'ec2_resource_prefix' and 'ec2_ami_image_id' variables - vars: - ec2_resource_prefix: "{{ custom_ami_name }}-prefix" - ec2_ami_image_id: "{{ source_ami_image_id }}" - - block: - - name: Create temporary file to store ssh private key - ansible.builtin.tempfile: - suffix: id_rsa - register: private_key - - - name: Include 'tasks/create_ec2_resources.yaml' file - ansible.builtin.include_tasks: tasks/create_ec2_resources.yaml - vars: - ec2_keypair_file: "{{ private_key.path }}" - - - name: Install required softwares and python modules - when: custom_ami_packages is defined - become: true - delegate_to: ec2 - block: - - name: Install packages - ansible.builtin.package: - name: "{{ item }}" - state: present - with_items: "{{ custom_ami_packages }}" - - - name: Create custom AMI from instance id - amazon.aws.ec2_ami: - instance_id: "{{ ec2_instance_id }}" - name: "{{ custom_ami_name }}" - wait: true - state: present - - always: - - name: Include 'tasks/delete_ec2_resources.yaml' file - ansible.builtin.include_tasks: tasks/delete_ec2_resources.yaml - - - name: Delete temporary file - ansible.builtin.file: - path: "{{ private_key.path }}" - state: absent - ignore_errors: true + always: + - name: Include 'tasks/delete_ec2_resources.yaml' file + ansible.builtin.include_tasks: tasks/delete_ec2_resources.yaml - name: Check that existing AMI found ansible.builtin.debug: msg: "Existing AMI found with name: '{{ custom_ami_name }}'" when: - - existing.images | length > 0 + - customized_ami__existing_amis.images | length > 0 - not (custom_ami_recreate_if_exists | bool) diff --git a/roles/customized_ami/tasks/create_ami.yaml b/roles/customized_ami/tasks/create_ami.yaml new file mode 100644 index 00000000..72f4ea28 --- /dev/null +++ b/roles/customized_ami/tasks/create_ami.yaml @@ -0,0 +1,16 @@ +--- +- name: Install required packages + when: custom_ami_packages is defined + become: true + delegate_to: ec2 + ansible.builtin.package: + name: "{{ item }}" + state: present + with_items: "{{ custom_ami_packages }}" + +- name: Create custom AMI from instance id + amazon.aws.ec2_ami: + instance_id: "{{ customized_ami__instance_id }}" + name: "{{ custom_ami_name }}" + wait: true + state: present diff --git a/roles/customized_ami/tasks/create_ec2_resources.yaml b/roles/customized_ami/tasks/create_ec2_resources.yaml index dabf8ba0..b00b1008 100644 --- a/roles/customized_ami/tasks/create_ec2_resources.yaml +++ b/roles/customized_ami/tasks/create_ec2_resources.yaml @@ -2,44 +2,41 @@ - name: Create a VPC to work in amazon.aws.ec2_vpc_net: cidr_block: "{{ custom_ami_vpc_cidr }}" - name: vpc-{{ ec2_resource_prefix }} - tags: - role: customized_ami - register: vpc + name: "{{ custom_ami_vpc_name }}" + tags: "{{ custom_ami_resource_tags }}" + register: customized_ami__vpc - name: Create a public subnet amazon.aws.ec2_vpc_subnet: - vpc_id: "{{ vpc.vpc.id }}" + vpc_id: "{{ customized_ami__vpc.vpc.id }}" cidr: "{{ custom_ami_subnet_cidr }}" - tags: - role: customized_ami - register: subnet + tags: "{{ custom_ami_resource_tags }}" + register: customized_ami__subnet - name: Create internet gateway attached to the VPC amazon.aws.ec2_vpc_igw: - vpc_id: "{{ vpc.vpc.id }}" - tags: - role: customized_ami + vpc_id: "{{ customized_ami__vpc.vpc.id }}" + tags: "{{ custom_ami_resource_tags }}" state: present - register: internet_gw + register: customized_ami__internet_gateway - name: Create Route table for internet gateway (public subnet) amazon.aws.ec2_vpc_route_table: - vpc_id: "{{ vpc.vpc.id }}" + vpc_id: "{{ customized_ami__vpc.vpc.id }}" subnets: - - "{{ subnet.subnet.id }}" + - "{{ customized_ami__subnet.subnet.id }}" routes: - dest: 0.0.0.0/0 - gateway_id: "{{ internet_gw.gateway_id }}" - tags: - role: customized_ami + gateway_id: "{{ customized_ami__internet_gateway.gateway_id }}" + lookup: tag + tags: "{{ custom_ami_resource_tags }}" state: present - name: Create security group allowing SSH connection amazon.aws.ec2_security_group: - name: "{{ ec2_resource_prefix }}-security" - vpc_id: "{{ vpc.vpc.id }}" - description: Security group allowing SSH connection to EC2 instance + name: "{{ custom_ami_security_group }}" + vpc_id: "{{ customized_ami__vpc.vpc.id }}" + description: "{{ custom_ami_security_group_desc }}" rules: - cidr_ip: 0.0.0.0/0 proto: tcp @@ -48,51 +45,47 @@ rules_egress: - cidr_ip: 0.0.0.0/0 proto: -1 - tags: - role: customized_ami + tags: "{{ custom_ami_resource_tags }}" state: present - register: secgroup + register: customized_ami__security_group - name: Create key pair to connect to the VM amazon.aws.ec2_key: - name: key-{{ ec2_resource_prefix }} - tags: - role: customized_ami - register: rsa_key - -- name: Save private key into file - ansible.builtin.copy: - content: "{{ rsa_key.key.private_key }}" - dest: "{{ ec2_keypair_file }}" - mode: 0400 - when: rsa_key is changed + name: "{{ custom_ami_key_name }}" + key_material: "{{ lookup('file', custom_ami_public_key_file) }}" + tags: "{{ custom_ami_resource_tags }}" - name: Create a virtual machine amazon.aws.ec2_instance: - name: ec2-default-{{ ec2_resource_prefix }} + name: "{{ custom_ami_ec2_instance_name }}" instance_type: "{{ custom_ami_ec2_instance_type }}" - image_id: "{{ ec2_ami_image_id }}" - key_name: key-{{ ec2_resource_prefix }} - subnet_id: "{{ subnet.subnet.id }}" + image_id: "{{ customized_ami__source_ami_image_id }}" + key_name: "{{ custom_ami_key_name }}" + subnet_id: "{{ customized_ami__subnet.subnet.id }}" network: assign_public_ip: true groups: - - "{{ secgroup.group_id }}" + - "{{ customized_ami__security_group.group_id }}" security_groups: - - "{{ secgroup.group_id }}" + - "{{ customized_ami__security_group.group_id }}" wait: true - tags: - role: customized_ami + tags: "{{ custom_ami_resource_tags }}" state: started - register: result + register: customized_ami__ec2 -- name: Set 'ec2_instance_id' variable +- name: Set 'customized_ami__instance_id' variable ansible.builtin.set_fact: - ec2_instance_id: "{{ result.instances.0.instance_id }}" + customized_ami__instance_id: "{{ customized_ami__ec2.instances.0.instance_id }}" - name: Add host to inventory ansible.builtin.add_host: hostname: ec2 ansible_ssh_user: "{{ source_ami_user_name }}" - ansible_host: "{{ result.instances.0.public_ip_address }}" - ansible_ssh_common_args: -o "UserKnownHostsFile=/dev/null" -o StrictHostKeyChecking=no -i {{ ec2_keypair_file }} + ansible_host: "{{ customized_ami__ec2.instances.0.public_ip_address }}" + ansible_ssh_common_args: -o "UserKnownHostsFile=/dev/null" -o StrictHostKeyChecking=no -i {{ custom_ami_private_key_file }} + ansible_python_interpreter: auto + +- name: Gather facts from ec2 instance + ansible.builtin.setup: + delegate_to: "ec2" + delegate_facts: true diff --git a/roles/customized_ami/tasks/delete.yaml b/roles/customized_ami/tasks/delete.yaml index d5500db5..4440ed93 100644 --- a/roles/customized_ami/tasks/delete.yaml +++ b/roles/customized_ami/tasks/delete.yaml @@ -3,7 +3,7 @@ amazon.aws.ec2_ami_info: filters: name: "{{ custom_ami_name }}" - register: existing + register: customized_ami__existing_amis - name: Delete AMI amazon.aws.ec2_ami: @@ -11,4 +11,7 @@ image_id: "{{ item.image_id }}" wait: true state: absent - with_items: "{{ existing.images }}" + with_items: "{{ customized_ami__existing_amis.images }}" + when: + - customized_ami__existing_amis.images | length > 0 + - (custom_ami_operation == 'create') | ternary(custom_ami_recreate_if_exists, 'true') | bool diff --git a/roles/customized_ami/tasks/delete_ec2_resources.yaml b/roles/customized_ami/tasks/delete_ec2_resources.yaml index 6c344eec..d4290462 100644 --- a/roles/customized_ami/tasks/delete_ec2_resources.yaml +++ b/roles/customized_ami/tasks/delete_ec2_resources.yaml @@ -2,79 +2,74 @@ - name: Get vpc information amazon.aws.ec2_vpc_net_info: filters: - tag:Name: vpc-{{ ec2_resource_prefix }} - register: vpc + tag:Name: "{{ custom_ami_vpc_name }}" + register: customized_ami__vpc - name: Delete EC2 resources - when: vpc.vpcs | length == 1 + when: customized_ami__vpc.vpcs | length == 1 block: - name: Set 'vpc_id' variable ansible.builtin.set_fact: - vpc_id: "{{ vpc.vpcs.0.vpc_id }}" + customized_ami__vpc_id: "{{ customized_ami__vpc.vpcs.0.vpc_id }}" - name: Get EC2 instance info amazon.aws.ec2_instance_info: filters: - instance-type: "{{ custom_ami_ec2_instance_type }}" - key-name: key-{{ ec2_resource_prefix }} - vpc-id: "{{ vpc_id }}" - tag:role: customized_ami - register: ec2_instance + vpc-id: "{{ customized_ami__vpc_id }}" + register: customized_ami__instances - name: Delete EC2 instance amazon.aws.ec2_instance: - instance_ids: - - "{{ ec2_instance.instances.0.instance_id }}" + instance_ids: "{{ customized_ami__instances.instances | map(attribute='instance_id') }}" wait: true state: terminated - when: ec2_instance.instances | length > 0 + when: customized_ami__instances.instances | length > 0 - name: Delete key pair to connect to the VM amazon.aws.ec2_key: - name: key-{{ ec2_resource_prefix }} + name: "{{ custom_ami_key_name }}" state: absent - name: List Security group from VPC amazon.aws.ec2_security_group_info: filters: - vpc-id: "{{ vpc_id }}" - tag:role: customized_ami - register: sg + vpc-id: "{{ customized_ami__vpc_id }}" + description: "{{ custom_ami_security_group_desc }}" + register: customized_ami__security_groups - name: Delete security groups amazon.aws.ec2_security_group: state: absent group_id: "{{ item }}" - with_items: "{{ sg.security_groups | map(attribute='group_id') | list }}" + with_items: "{{ customized_ami__security_groups.security_groups | map(attribute='group_id') | list }}" - name: List routes table from VPC amazon.aws.ec2_vpc_route_table_info: filters: - vpc-id: "{{ vpc_id }}" - tag:role: customized_ami - register: route_table + vpc-id: "{{ customized_ami__vpc_id }}" + association.main: false + register: customized_ami__route_table - name: Delete VPC route table amazon.aws.ec2_vpc_route_table: route_table_id: "{{ item }}" - vpc_id: "{{ vpc_id }}" + vpc_id: "{{ customized_ami__vpc_id }}" lookup: id state: absent - with_items: "{{ route_table.route_tables | map(attribute='id') | list }}" + with_items: "{{ customized_ami__route_table.route_tables | map(attribute='id') | list }}" - name: Delete internet gateway amazon.aws.ec2_vpc_igw: - vpc_id: "{{ vpc_id }}" + vpc_id: "{{ customized_ami__vpc_id }}" state: absent - name: Delete subnets amazon.aws.ec2_vpc_subnet: cidr: "{{ custom_ami_subnet_cidr }}" state: absent - vpc_id: "{{ vpc_id }}" + vpc_id: "{{ customized_ami__vpc_id }}" - name: Delete VPC amazon.aws.ec2_vpc_net: - name: vpc-{{ ec2_resource_prefix }} - cidr_block: "{{ custom_ami_vpc_cidr }}" + vpc_id: "{{ customized_ami__vpc_id }}" state: absent diff --git a/roles/customized_ami/tasks/main.yml b/roles/customized_ami/tasks/main.yml index e2e96714..15d9aec8 100644 --- a/roles/customized_ami/tasks/main.yml +++ b/roles/customized_ami/tasks/main.yml @@ -6,7 +6,7 @@ - name: Run 'customized_ami' role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: - name: Include file diff --git a/roles/customized_ami/tasks/read_source_ami.yaml b/roles/customized_ami/tasks/read_source_ami.yaml new file mode 100644 index 00000000..240eef8a --- /dev/null +++ b/roles/customized_ami/tasks/read_source_ami.yaml @@ -0,0 +1,24 @@ +--- +- name: Set source AMI + ansible.builtin.set_fact: + customized_ami__source_ami_image_id: "{{ source_ami_image_id }}" + when: source_ami_image_id is defined + +- name: Define source AMI image id when not supplied as input + when: source_ami_image_id is undefined + block: + - name: Get source AMI image ID using filters + amazon.aws.ec2_ami_info: + filters: "{{ source_ami_filters }}" + register: customized_ami__source_images + # very spammy + no_log: true + + - name: Fail when no AMI found using filters + ansible.builtin.fail: + msg: No AMI found using filters + when: customized_ami__source_images.images | length == 0 + + - name: Define source AMI as variable + ansible.builtin.set_fact: + customized_ami__source_ami_image_id: "{{ customized_ami__source_images.images.0.image_id }}" diff --git a/roles/ec2_instance_terminate_by_tag/tasks/main.yml b/roles/ec2_instance_terminate_by_tag/tasks/main.yml index b5653a55..43bb9604 100644 --- a/roles/ec2_instance_terminate_by_tag/tasks/main.yml +++ b/roles/ec2_instance_terminate_by_tag/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: Run 'ec2_instance_terminate_by_tag' role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: - name: Verify that tag to terminate instances with was provided @@ -11,16 +11,16 @@ - name: Prepare filters dict to filter running instances with specified tag ansible.builtin.set_fact: - instance_filters: "{{ {'instance-state-name': 'running', 'tag:' + tag_key_to_terminate_instances: tag_value_to_terminate_instances} }}" + ec2_instance_terminate_by_tag__filters: "{{ {'instance-state-name': 'running', 'tag:' + tag_key_to_terminate_instances: tag_value_to_terminate_instances} }}" - name: Get instances to be terminated amazon.aws.ec2_instance_info: - filters: "{{ instance_filters }}" - register: tagged_instances + filters: "{{ ec2_instance_terminate_by_tag__filters }}" + register: ec2_instance_terminate_by_tag__tagged_instances - name: Create a list of instance ids to be terminated ansible.builtin.set_fact: - instance_ids: "{{ tagged_instances.instances | map(attribute='instance_id') | list }}" + ec2_instance_terminate_by_tag__instance_ids: "{{ ec2_instance_terminate_by_tag__tagged_instances.instances | map(attribute='instance_id') | list }}" - name: Disable 'termination_protection' when: terminate_protected_instances @@ -30,31 +30,32 @@ msg: - "'terminate_protected_instances' is set to True..." - Instances with termination protection enabled will also be terminated... - when: instance_ids | length != 0 + when: ec2_instance_terminate_by_tag__instance_ids | length != 0 - name: Disable instance termination protection if terminate_protected_instances is true amazon.aws.ec2_instance: instance_ids: - "{{ item }}" termination_protection: false - with_items: "{{ instance_ids }}" + with_items: "{{ ec2_instance_terminate_by_tag__instance_ids }}" - name: Terminate instances amazon.aws.ec2_instance: instance_ids: - "{{ item }}" state: absent - register: terminate_result + register: ec2_instance_terminate_by_tag__terminate_result with_items: - - "{{ instance_ids }}" + - "{{ ec2_instance_terminate_by_tag__instance_ids }}" always: - name: Create list of terminated instances ansible.builtin.set_fact: - terminated_instances: "{{ terminate_result.results | map(attribute='terminate_success') | list | flatten }}" + ec2_instance_terminate_by_tag__terminated_instances: "{{ ec2_instance_terminate_by_tag__terminate_result.results | map(attribute='terminate_success') | list | flatten }}" + when: ec2_instance_terminate_by_tag__terminate_result is defined - name: Verify that the instances have been successfully terminated ansible.builtin.debug: msg: - - Terminated instances successfully -> {{ terminated_instances }} - when: terminated_instances | length != 0 + - Terminated instances successfully -> {{ ec2_instance_terminate_by_tag__terminated_instances }} + when: ec2_instance_terminate_by_tag__terminated_instances | length != 0 diff --git a/roles/enable_cloudtrail_encryption_with_kms/tasks/main.yml b/roles/enable_cloudtrail_encryption_with_kms/tasks/main.yml index f1143e72..1975577d 100644 --- a/roles/enable_cloudtrail_encryption_with_kms/tasks/main.yml +++ b/roles/enable_cloudtrail_encryption_with_kms/tasks/main.yml @@ -3,7 +3,7 @@ - name: Run 'enable_cloudtrail_encryption_with_kms' role module_defaults: - group/aws: "{{ aws_role_credentials }}" + group/aws: "{{ aws_setup_credentials__output }}" block: - name: Fail when 'enable_cloudtrail_encryption_with_kms_trail_name' is not defined @@ -20,51 +20,46 @@ amazon.aws.cloudtrail_info: trail_names: - "{{ enable_cloudtrail_encryption_with_kms_trail_name }}" - register: __trail_info + register: enable_cloudtrail_encryption_with_kms__trail_info - name: Fail when the trail does not exist ansible.builtin.fail: msg: "The trail does not exist: {{ enable_cloudtrail_encryption_with_kms_trail_name }}" - when: __trail_info.trail_list | length == 0 + when: enable_cloudtrail_encryption_with_kms__trail_info.trail_list | length == 0 - name: Gather information about the KMS key amazon.aws.kms_key_info: key_id: "{{ enable_cloudtrail_encryption_with_kms_kms_key_id }}" - register: __kms_key_info + register: enable_cloudtrail_encryption_with_kms__kms_key_info - name: Gather information about the KMS key using alias amazon.aws.kms_key_info: alias: "{{ enable_cloudtrail_encryption_with_kms_kms_key_id }}" - register: __kms_key_info - when: __kms_key_info.kms_keys | length == 0 + register: enable_cloudtrail_encryption_with_kms__kms_key_info + when: enable_cloudtrail_encryption_with_kms__kms_key_info.kms_keys | length == 0 - name: Fail when the KMS key does not exist ansible.builtin.fail: msg: "The KMS key does not exist: {{ enable_cloudtrail_encryption_with_kms_trail_name }}" - when: __kms_key_info.kms_keys | length == 0 - - - name: Set 'kms_key_arn' variable - ansible.builtin.set_fact: - kms_key_arn: "{{ __kms_key_info.kms_keys.0.key_arn }}" + when: enable_cloudtrail_encryption_with_kms__kms_key_info.kms_keys | length == 0 - name: Enable encryption on the trail amazon.aws.cloudtrail: state: present name: "{{ enable_cloudtrail_encryption_with_kms_trail_name }}" - kms_key_id: "{{ kms_key_arn }}" + kms_key_id: "{{ enable_cloudtrail_encryption_with_kms__kms_key_info.kms_keys.0.key_arn }}" s3_bucket_name: "{{__trail_info.trail_list.0.s3_bucket_name}}" s3_key_prefix: "{{__trail_info.trail_list.0.s3_key_prefix}}" - register: __enable_encyption - name: Verify that encryption has been enabled on the CloudTrail trail amazon.aws.cloudtrail_info: trail_names: - "{{ enable_cloudtrail_encryption_with_kms_trail_name }}" - register: __verify_encryption + register: enable_cloudtrail_encryption_with_kms__verify_encryption - name: Assert that AWS CloudTrail trail was successfully encrypted ansible.builtin.assert: that: - - __verify_encryption.trail_list.0.kms_key_id == kms_key_arn + - enable_cloudtrail_encryption_with_kms__verify_encryption.trail_list.0.kms_key_id == enable_cloudtrail_encryption_with_kms__kms_key_info.kms_keys.0.key_arn success_msg: AWS CloudTrail trail was successfully encrypted fail_msg: AWS CloudTrail trail was not successfully encrypted diff --git a/tests/integration/targets/test_aws_setup_credentials/aliases b/tests/integration/targets/test_aws_setup_credentials/aliases new file mode 100644 index 00000000..6d08c595 --- /dev/null +++ b/tests/integration/targets/test_aws_setup_credentials/aliases @@ -0,0 +1,3 @@ +cloud/aws +role/aws_setup_credentials +time=10s diff --git a/tests/integration/targets/test_aws_setup_credentials/defaults/main.yml b/tests/integration/targets/test_aws_setup_credentials/defaults/main.yml deleted file mode 100644 index 5526c7bf..00000000 --- a/tests/integration/targets/test_aws_setup_credentials/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# defaults file for test_aws_setup_credentials diff --git a/tests/integration/targets/test_aws_setup_credentials/tasks/main.yml b/tests/integration/targets/test_aws_setup_credentials/tasks/main.yml index 8c169815..8404312d 100644 --- a/tests/integration/targets/test_aws_setup_credentials/tasks/main.yml +++ b/tests/integration/targets/test_aws_setup_credentials/tasks/main.yml @@ -3,12 +3,15 @@ ansible.builtin.include_role: name: cloud.aws_ops.aws_setup_credentials vars: - aws_profile: profile-1 + aws_security_token: '{{ security_token | default(omit) }}' -- name: Ensure credentials contain only aws_profile key - ansible.builtin.assert: - that: - - aws_role_credentials is defined - - aws_role_credentials.keys() | length == 1 - - '"aws_profile" in aws_role_credentials' - - aws_role_credentials.aws_profile == 'profile-1' +- name: Trying calling module using generating credentials + module_defaults: + group/aws: + "{{ aws_setup_credentials__output }}" + block: + + - name: Get instances to be terminated + amazon.aws.ec2_instance_info: + filters: + instance-state-name: 'running' diff --git a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/aliases b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/aliases new file mode 100644 index 00000000..c1f61042 --- /dev/null +++ b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/aliases @@ -0,0 +1,3 @@ +cloud/aws +time=5m +role/awsconfig_detach_and_delete_internet_gateway \ No newline at end of file diff --git a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/defaults/main.yml b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/defaults/main.yml index 73cc4a1d..c4628e95 100644 --- a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/defaults/main.yml +++ b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/defaults/main.yml @@ -1,11 +1,13 @@ --- # defaults file for awsconfig_detach_and_delete_internet_gateway +aws_security_token: '{{ security_token | default(omit) }}' test_image_filter: architecture: x86_64 virtualization-type: hvm root-device-type: ebs - name: Fedora-Cloud-Base-35-* + name: Fedora-Cloud-Base-37-* -test_vpc_cidr: 172.10.0.0/16 -test_subnet_cidr: 172.10.0.0/24 -test_ec2_instance_name: ec2fedora +test_vpc_name: "vpc-{{ resource_prefix }}" +test_vpc_cidr: "172.{{ 255 | random(seed=resource_prefix) }}.0.0/16" +test_subnet_cidr: "172.{{ 255 | random(seed=resource_prefix) }}.0.0/24" +test_ec2_instance_name: "ec2-{{ resource_prefix }}" diff --git a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/main.yml b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/main.yml index adc4b824..48b7ae75 100644 --- a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/main.yml +++ b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/main.yml @@ -1,8 +1,4 @@ --- -- name: Set 'test_vpc_name' variable - ansible.builtin.set_fact: - test_vpc_name: ansible-vpc-{{ 101 | random(1, 10) }} - - name: Test 'awsconfig_detach_and_delete_internet_gateway' role module_defaults: group/aws: @@ -21,13 +17,11 @@ name: cloud.aws_ops.awsconfig_detach_and_delete_internet_gateway apply: ignore_errors: true - vars: - internet_gateway_id: "{{ igw.gateway_id }}" - name: Ensure internet gateway was not deleted (public ip addresses to unmap before) amazon.aws.ec2_vpc_igw_info: internet_gateway_ids: - - "{{ igw.gateway_id }}" + - "{{ internet_gateway_id }}" register: result - name: Assert that internet gateway was not deleted @@ -39,13 +33,13 @@ - name: Get EC2 instance info amazon.aws.ec2_instance_info: filters: - vpc-id: "{{ vpc.vpc.id }}" - register: result + vpc-id: "{{ test_vpc_id }}" + register: _instances - name: Delete EC2 instances with dependant Resources amazon.aws.ec2_instance: instance_ids: - - "{{ result.instances.0.instance_id }}" + - "{{ _instances.instances.0.instance_id }}" wait: true state: terminated @@ -53,13 +47,11 @@ - name: Include 'awsconfig_detach_and_delete_internet_gateway' role ansible.builtin.include_role: name: cloud.aws_ops.awsconfig_detach_and_delete_internet_gateway - vars: - internet_gateway_id: "{{ igw.gateway_id }}" - name: Ensure internet gateway does not exist anymore amazon.aws.ec2_vpc_igw_info: internet_gateway_ids: - - "{{ igw.gateway_id }}" + - "{{ internet_gateway_id }}" register: result ignore_errors: true diff --git a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/setup.yml b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/setup.yml index 56069b76..7d921067 100644 --- a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/setup.yml +++ b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/setup.yml @@ -1,49 +1,65 @@ --- -- name: Create a VPC to work in - amazon.aws.ec2_vpc_net: - cidr_block: "{{ test_vpc_cidr }}" - name: "{{ test_vpc_name }}" - register: vpc +- name: Setup + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: Create a VPC to work in + amazon.aws.ec2_vpc_net: + cidr_block: "{{ test_vpc_cidr }}" + name: "{{ test_vpc_name }}" + register: vpc -- name: Create Subnet for EC2 instance - amazon.aws.ec2_vpc_subnet: - vpc_id: "{{ vpc.vpc.id }}" - cidr: "{{ test_subnet_cidr }}" - register: subnet + - name: Set variable for VPC id + ansible.builtin.set_fact: + test_vpc_id: "{{ vpc.vpc.id }}" -- name: Create internet gateway attached to the VPC - amazon.aws.ec2_vpc_igw: - vpc_id: "{{ vpc.vpc.id }}" - state: present - register: igw + - name: Create Subnet for EC2 instance + amazon.aws.ec2_vpc_subnet: + vpc_id: "{{ test_vpc_id }}" + cidr: "{{ test_subnet_cidr }}" + register: subnet -- name: Create Route table for internet gateway (public subnet) - amazon.aws.ec2_vpc_route_table: - vpc_id: "{{ vpc.vpc.id }}" - subnets: - - "{{ subnet.subnet.id }}" - routes: - - dest: 0.0.0.0/0 - gateway_id: "{{ igw.gateway_id }}" - lookup: tag - resource_tags: - subnet: public - route: internet - state: present + - name: Create internet gateway attached to the VPC + amazon.aws.ec2_vpc_igw: + vpc_id: "{{ test_vpc_id }}" + state: present + register: igw -- name: Get image ID to create an instance - amazon.aws.ec2_ami_info: - filters: "{{ test_image_filter }}" - register: images + - name: Set variable for internet gateway Id + ansible.builtin.set_fact: + internet_gateway_id: "{{ igw.gateway_id }}" -- name: Create a virtual machine - amazon.aws.ec2_instance: - name: "{{ test_ec2_instance_name }}" - instance_type: t2.micro - image_id: "{{ images.images.0.image_id }}" - subnet_id: "{{ subnet.subnet.id }}" - network: - assign_public_ip: true - wait: true - state: started - register: result + - name: Create Route table for internet gateway (public subnet) + amazon.aws.ec2_vpc_route_table: + vpc_id: "{{ test_vpc_id }}" + subnets: + - "{{ subnet.subnet.id }}" + routes: + - dest: 0.0.0.0/0 + gateway_id: "{{ igw.gateway_id }}" + lookup: tag + resource_tags: + subnet: public + route: internet + state: present + + - name: Get image ID to create an instance + amazon.aws.ec2_ami_info: + filters: "{{ test_image_filter }}" + register: images + + - name: Create a virtual machine + amazon.aws.ec2_instance: + name: "{{ test_ec2_instance_name }}" + instance_type: t2.micro + image_id: "{{ images.images.0.image_id }}" + subnet_id: "{{ subnet.subnet.id }}" + network: + assign_public_ip: true + wait: false + state: started + register: result diff --git a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/teardown.yml b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/teardown.yml index 497d4f83..8f1ecac4 100644 --- a/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/teardown.yml +++ b/tests/integration/targets/test_awsconfig_detach_and_delete_internet_gateway/tasks/teardown.yml @@ -1,58 +1,51 @@ --- -- name: Get vpc information - amazon.aws.ec2_vpc_net_info: - filters: - tag:Name: "{{ test_vpc_name }}" - register: vpc - - name: Teardown - when: vpc.vpcs | length == 1 + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" block: - - name: Set 'vpc_id' variable - ansible.builtin.set_fact: - vpc_id: "{{ vpc.vpcs.0.vpc_id }}" - - name: Get EC2 instance info amazon.aws.ec2_instance_info: filters: - vpc-id: "{{ vpc_id }}" - register: result + vpc-id: "{{ test_vpc_id }}" + register: _instances - - name: Delete EC2 instances with dependant Resources - when: result.instances | length == 1 - block: - - name: Delete EC2 instance - amazon.aws.ec2_instance: - instance_ids: - - "{{ result.instances.0.instance_id }}" - wait: true - state: terminated + - name: Delete EC2 instances + amazon.aws.ec2_instance: + instance_ids: + - "{{ _instances.instances.0.instance_id }}" + wait: true + state: terminated + when: _instances.instances | length == 1 - name: List routes table from VPC amazon.aws.ec2_vpc_route_table_info: filters: - vpc-id: "{{ vpc_id }}" + vpc-id: "{{ test_vpc_id }}" association.main: false register: route_table - name: Delete VPC route table amazon.aws.ec2_vpc_route_table: route_table_id: "{{ item }}" - vpc_id: "{{ vpc_id }}" + vpc_id: "{{ test_vpc_id }}" lookup: id state: absent with_items: "{{ route_table.route_tables | map(attribute='id') | list }}" - name: Delete internet gateway amazon.aws.ec2_vpc_igw: - vpc_id: "{{ vpc_id }}" + vpc_id: "{{ test_vpc_id }}" state: absent - name: Delete subnets amazon.aws.ec2_vpc_subnet: cidr: "{{ test_subnet_cidr }}" state: absent - vpc_id: "{{ vpc_id }}" + vpc_id: "{{ test_vpc_id }}" - name: Delete VPC amazon.aws.ec2_vpc_net: diff --git a/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/aliases b/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/aliases new file mode 100644 index 00000000..ca30eda8 --- /dev/null +++ b/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/aliases @@ -0,0 +1,4 @@ +cloud/aws +role/awsconfig_multiregion_cloudtrail +time=20s +disabled # reason: need update terminator first with permission 'cloudtrail:DescribeTrails' \ No newline at end of file diff --git a/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/defaults/main.yml b/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/defaults/main.yml index ed97d539..73299d5d 100644 --- a/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/defaults/main.yml +++ b/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/defaults/main.yml @@ -1 +1,4 @@ --- +aws_security_token: '{{ security_token | default(omit) }}' +s3_bucket_name: "s3-{{ resource_prefix }}" +cloud_trail_name: "trail-{{ resource_prefix }}" diff --git a/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/tasks/main.yml b/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/tasks/main.yml index 43ccf3f6..914f83c9 100644 --- a/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/tasks/main.yml +++ b/tests/integration/targets/test_awsconfig_multiregion_cloudtrail/tasks/main.yml @@ -1,17 +1,12 @@ --- -- name: Set 'test_resource_prefix' variable - ansible.builtin.set_fact: - test_resource_prefix: ansible-multiregion-cloudtrail-{{ 101 | random(1, 10) }} - - name: Test 'awsconfig_multiregion_cloudtrail' role block: - - name: Set 's3_bucket_name' and 'cloud_trail_name' variables - ansible.builtin.set_fact: - s3_bucket_name: s3-{{ test_resource_prefix }} - cloud_trail_name: trail-{{ test_resource_prefix }} - - name: Create S3 Bucket amazon.aws.s3_bucket: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" name: "{{ s3_bucket_name }}" state: present policy: "{{ lookup('template', 'policy.json') }}" @@ -27,6 +22,22 @@ key_prefix: ansible # Validate that the cloud trail has been created + - name: Validate that cloud trail has been created + amazon.aws.cloudtrail_info: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + trail_names: + - "{{ cloud_trail_name }}" + register: _trail + + - name: Ensure that cloud trail was created as expected + ansible.builtin.assert: + that: + - _trail.trail_list.0.is_multi_region_trail + - _trail.trail_list.0.s3_bucket_name == s3_bucket_name + - _trail.trail_list.0.is_logging # Delete cloud trail - name: Create Multi-region cloud trail @@ -36,11 +47,32 @@ operation: delete trail_name: "{{ cloud_trail_name }}" + # Validate that the cloud trail has been deleted + - name: Validate that cloud trail has been deleted + amazon.aws.cloudtrail_info: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + trail_names: + - "{{ cloud_trail_name }}" + register: _trail + + - name: Ensure that cloud trail was created as expected + ansible.builtin.assert: + that: + - _trail.trail_list | length == 0 + # Validate that the cloud trail has been deleted always: - name: Delete S3 bucket amazon.aws.s3_bucket: - name: s3-{{ s3_bucket_name }} + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + name: "{{ s3_bucket_name }}" state: absent + force: true ignore_errors: true diff --git a/tests/integration/targets/test_customized_ami/aliases b/tests/integration/targets/test_customized_ami/aliases index 7a68b11d..a30bbee3 100644 --- a/tests/integration/targets/test_customized_ami/aliases +++ b/tests/integration/targets/test_customized_ami/aliases @@ -1 +1,3 @@ -disabled +cloud/aws +role/customized_ami +time=40m diff --git a/tests/integration/targets/test_customized_ami/defaults/main.yml b/tests/integration/targets/test_customized_ami/defaults/main.yml index 46f9a798..93b69e8d 100644 --- a/tests/integration/targets/test_customized_ami/defaults/main.yml +++ b/tests/integration/targets/test_customized_ami/defaults/main.yml @@ -1,7 +1,13 @@ --- -ami_initial_packages: - - podman -ami_update_packages: - - libvirt +aws_security_token: '{{ security_token | default(omit) }}' +custom_ami_name: "ami-{{ resource_prefix }}" ami_infra_vpc_cidr: 172.1.0.0/16 ami_infra_subnet_cidr: 172.1.0.0/24 +ami_vpc_name: "vpc-{{ resource_prefix }}" +ami_security_group: "security-group-{{ resource_prefix }}" +ami_security_group_desc: "Allow connection to instance via SSH port" +ami_key_name: "key-{{ resource_prefix }}" +ami_public_key_file: ~/.ssh/id_rsa.pub +ami_private_key_file: ~/.ssh/id_rsa.pub +ami_user_name: fedora +ami_ec2_instance_type: t2.micro diff --git a/tests/integration/targets/test_customized_ami/tasks/create.yml b/tests/integration/targets/test_customized_ami/tasks/create.yml deleted file mode 100644 index 75ffdc1d..00000000 --- a/tests/integration/targets/test_customized_ami/tasks/create.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Include 'customized_ami' role - ansible.builtin.include_role: - name: cloud.aws_ops.customized_ami - vars: - custom_ami_packages: "{{ ami_initial_packages }}" diff --git a/tests/integration/targets/test_customized_ami/tasks/create_infra.yml b/tests/integration/targets/test_customized_ami/tasks/create_infra.yml index cee55ee4..3ffae4e8 100644 --- a/tests/integration/targets/test_customized_ami/tasks/create_infra.yml +++ b/tests/integration/targets/test_customized_ami/tasks/create_infra.yml @@ -1,108 +1,96 @@ --- -- name: Create a VPC to work in - amazon.aws.ec2_vpc_net: - cidr_block: "{{ ami_infra_vpc_cidr }}" - name: vpc-{{ test_resource_prefix }} - tags: - test: "{{ test_resource_prefix }}" - register: vpc - -- name: Create a public subnet - amazon.aws.ec2_vpc_subnet: - vpc_id: "{{ vpc.vpc.id }}" - cidr: "{{ ami_infra_subnet_cidr }}" - tags: - test: "{{ test_resource_prefix }}" - register: subnet +- name: Create EC2 resources + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: Create a VPC to work in + amazon.aws.ec2_vpc_net: + cidr_block: "{{ ami_infra_vpc_cidr }}" + name: "{{ ami_vpc_name }}" + register: test__vpc -- name: Create internet gateway attached to the VPC - amazon.aws.ec2_vpc_igw: - vpc_id: "{{ vpc.vpc.id }}" - tags: - test: "{{ test_resource_prefix }}" - state: present - register: igw + - name: Create a public subnet + amazon.aws.ec2_vpc_subnet: + vpc_id: "{{ test__vpc.vpc.id }}" + cidr: "{{ ami_infra_subnet_cidr }}" + register: test__subnet -- name: Create Route table for internet gateway (public subnet) - amazon.aws.ec2_vpc_route_table: - vpc_id: "{{ vpc.vpc.id }}" - subnets: - - "{{ subnet.subnet.id }}" - routes: - - dest: 0.0.0.0/0 - gateway_id: "{{ igw.gateway_id }}" - tags: - test: "{{ test_resource_prefix }}" - state: present + - name: Create internet gateway attached to the VPC + amazon.aws.ec2_vpc_igw: + vpc_id: "{{ test__vpc.vpc.id }}" + state: present + register: test__internet_gateway -- name: Create security group allowing SSH connection - amazon.aws.ec2_security_group: - name: "{{ test_resource_prefix }}-security" - vpc_id: "{{ vpc.vpc.id }}" - description: Security group for EC2 instance SSH - rules: - - cidr_ip: 0.0.0.0/0 - proto: tcp - from_port: 22 - to_port: 22 - rules_egress: - - cidr_ip: 0.0.0.0/0 - proto: -1 - tags: - test: "{{ test_resource_prefix }}" - state: present - register: secgroup + - name: Create Route table for internet gateway (public subnet) + amazon.aws.ec2_vpc_route_table: + vpc_id: "{{ test__vpc.vpc.id }}" + subnets: + - "{{ test__subnet.subnet.id }}" + routes: + - dest: 0.0.0.0/0 + gateway_id: "{{ test__internet_gateway.gateway_id }}" + lookup: tag + tags: + ansible_test_prefix: "{{ resource_prefix }}" + state: present -- name: Create key pair to connect to the VM - amazon.aws.ec2_key: - name: key-{{ test_resource_prefix }} - tags: - test: "{{ test_resource_prefix }}" - register: rsa_key + - name: Create security group allowing SSH connection + amazon.aws.ec2_security_group: + name: "{{ ami_security_group }}" + vpc_id: "{{ test__vpc.vpc.id }}" + description: "{{ ami_security_group_desc }}" + rules: + - cidr_ip: 0.0.0.0/0 + proto: tcp + from_port: 22 + to_port: 22 + rules_egress: + - cidr_ip: 0.0.0.0/0 + proto: -1 + state: present + register: test__security_group -- name: Copy RSA private key content into file - ansible.builtin.copy: - content: "{{ rsa_key.key.private_key }}" - dest: "{{ keyfile_path }}" - mode: 0400 - when: rsa_key is changed + - name: Create key pair to connect to the VM + amazon.aws.ec2_key: + name: "{{ ami_key_name }}" + key_material: "{{ lookup('file', ami_public_key_file) }}" -- name: Create EC2 and update inventory with - when: ec2_instance_name is defined - block: - name: Get custom AMI information amazon.aws.ec2_ami_info: filters: name: "{{ custom_ami_name }}" - register: ami_info + register: test__amis - name: Fail when AMI with name is not found ansible.builtin.fail: msg: "Unable to find AMI with name: {{ custom_ami_name }}" - when: ami_info.images | length == 0 + when: test__amis.images | length == 0 - name: Create a virtual machine amazon.aws.ec2_instance: - name: "{{ ec2_instance_name }}" - instance_type: t2.micro - image_id: "{{ ami_info.images.0.image_id }}" - key_name: key-{{ test_resource_prefix }} - subnet_id: "{{ subnet.subnet.id }}" + name: "{{ ami_ec2_instance_name }}" + instance_type: "{{ ami_ec2_instance_type }}" + image_id: "{{ test__amis.images.0.image_id }}" + key_name: "{{ ami_key_name }}" + subnet_id: "{{ test__subnet.subnet.id }}" network: assign_public_ip: true groups: - - "{{ secgroup.group_id }}" + - "{{ test__security_group.group_id }}" security_groups: - - "{{ secgroup.group_id }}" + - "{{ test__security_group.group_id }}" wait: true - tags: - test: "{{ test_resource_prefix }}" state: started - register: result + register: test__ec2_instance - name: Add host to inventory ansible.builtin.add_host: - name: "{{ ec2_instance_name }}" - ansible_ssh_user: fedora - ansible_host: "{{ result.instances.0.public_ip_address }}" - ansible_ssh_common_args: -o "UserKnownHostsFile=/dev/null" -o StrictHostKeyChecking=no -i {{ keyfile_path }} + hostname: "{{ ami_ec2_instance_name }}" + ansible_ssh_user: "{{ ami_user_name }}" + ansible_host: "{{ test__ec2_instance.instances.0.public_ip_address }}" + ansible_ssh_common_args: -o "UserKnownHostsFile=/dev/null" -o StrictHostKeyChecking=no -i {{ ami_private_key_file }} + ansible_python_interpreter: auto diff --git a/tests/integration/targets/test_customized_ami/tasks/delete.yml b/tests/integration/targets/test_customized_ami/tasks/delete.yml deleted file mode 100644 index dac07eba..00000000 --- a/tests/integration/targets/test_customized_ami/tasks/delete.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Include 'customized_ami' role - ansible.builtin.include_role: - name: cloud.aws_ops.customized_ami - vars: - custom_ami_operation: delete diff --git a/tests/integration/targets/test_customized_ami/tasks/delete_infra.yml b/tests/integration/targets/test_customized_ami/tasks/delete_infra.yml index 5d3d89b2..52b5ae03 100644 --- a/tests/integration/targets/test_customized_ami/tasks/delete_infra.yml +++ b/tests/integration/targets/test_customized_ami/tasks/delete_infra.yml @@ -1,76 +1,83 @@ --- -- name: Get vpc information - amazon.aws.ec2_vpc_net_info: - filters: - tag:Name: vpc-{{ test_resource_prefix }} - register: vpcinfo - -- name: Delete resource created to test custom AMI - when: vpcinfo.vpcs | length == 1 +- name: Delete EC2 resources + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" block: - - name: Set 'vpc_id' variable - ansible.builtin.set_fact: - vpc_id: "{{ vpcinfo.vpcs.0.vpc_id }}" - - - name: Get EC2 instance info - amazon.aws.ec2_instance_info: + - name: Get vpc information + amazon.aws.ec2_vpc_net_info: filters: - vpc-id: "{{ vpc_id }}" - tag:test: "{{ test_resource_prefix }}" - register: ec2_instance + tag:Name: "{{ ami_vpc_name }}" + register: test__vpc - - name: Delete EC2 instance - amazon.aws.ec2_instance: - instance_ids: "{{ ec2_instance.instances | map(attribute='instance_id') | list }}" - wait: true - state: terminated - when: ec2_instance.instances | length > 0 + - name: Delete EC2 resources + when: test__vpc.vpcs | length == 1 + block: + - name: Set 'test__vpc_id' variable + ansible.builtin.set_fact: + test__vpc_id: "{{ test__vpc.vpcs.0.vpc_id }}" - - name: Delete key pair to connect to the bastion VM - amazon.aws.ec2_key: - name: key-{{ test_resource_prefix }} - state: absent + - name: Get EC2 instance info + amazon.aws.ec2_instance_info: + filters: + vpc-id: "{{ test__vpc_id }}" + register: test__instances - - name: List Security group from VPC - amazon.aws.ec2_group_info: - filters: - vpc-id: "{{ vpc_id }}" - tag:test: "{{ test_resource_prefix }}" - register: sg + - name: Delete EC2 instance + amazon.aws.ec2_instance: + instance_ids: "{{ test__instances.instances | map(attribute='instance_id') }}" + wait: true + state: terminated + when: test__instances.instances | length > 0 - - name: Delete security groups - amazon.aws.ec2_group: - state: absent - group_id: "{{ item }}" - with_items: "{{ sg.security_groups | map(attribute='group_id') | list }}" + - name: Delete key pair to connect to the VM + amazon.aws.ec2_key: + name: "{{ ami_key_name }}" + state: absent - - name: List routes table from VPC - amazon.aws.ec2_vpc_route_table_info: - filters: - vpc-id: "{{ vpc_id }}" - tag:test: "{{ test_resource_prefix }}" - register: route_table + - name: List Security group from VPC + amazon.aws.ec2_security_group_info: + filters: + vpc-id: "{{ test__vpc_id }}" + description: "{{ ami_security_group_desc }}" + register: test__security_groups + + - name: Delete security groups + amazon.aws.ec2_security_group: + state: absent + group_id: "{{ item }}" + with_items: "{{ test__security_groups.security_groups | map(attribute='group_id') | list }}" + + - name: List routes table from VPC + amazon.aws.ec2_vpc_route_table_info: + filters: + vpc-id: "{{ test__vpc_id }}" + association.main: false + register: test__route_table - - name: Delete VPC route table - amazon.aws.ec2_vpc_route_table: - route_table_id: "{{ item }}" - vpc_id: "{{ vpc_id }}" - state: absent - with_items: "{{ route_table.route_tables | map(attribute='id') | list }}" + - name: Delete VPC route table + amazon.aws.ec2_vpc_route_table: + route_table_id: "{{ item }}" + vpc_id: "{{ test__vpc_id }}" + lookup: id + state: absent + with_items: "{{ test__route_table.route_tables | map(attribute='id') | list }}" - - name: Delete internet gateway - amazon.aws.ec2_vpc_igw: - vpc_id: "{{ vpc_id }}" - state: absent + - name: Delete internet gateway + amazon.aws.ec2_vpc_igw: + vpc_id: "{{ test__vpc_id }}" + state: absent - - name: Delete subnets - amazon.aws.ec2_vpc_subnet: - cidr: "{{ ami_infra_subnet_cidr }}" - state: absent - vpc_id: "{{ vpc_id }}" + - name: Delete subnets + amazon.aws.ec2_vpc_subnet: + cidr: "{{ ami_infra_subnet_cidr }}" + state: absent + vpc_id: "{{ test__vpc_id }}" - - name: Delete VPC - amazon.aws.ec2_vpc_net: - name: "{{ vpcinfo.vpcs.0.tags.Name }}" - cidr_block: "{{ vpcinfo.vpcs.0.cidr_block }}" - state: absent + - name: Delete VPC + amazon.aws.ec2_vpc_net: + vpc_id: "{{ test__vpc_id }}" + state: absent diff --git a/tests/integration/targets/test_customized_ami/tasks/main.yml b/tests/integration/targets/test_customized_ami/tasks/main.yml index 4d57a711..f2c331eb 100644 --- a/tests/integration/targets/test_customized_ami/tasks/main.yml +++ b/tests/integration/targets/test_customized_ami/tasks/main.yml @@ -1,98 +1,93 @@ --- -- name: Set 'test_resource_prefix' variable +- name: Test role 'customized_ami' vars: - # test_resource_prefix: "{{ lookup('password', '/dev/null chars=ascii_letters,digits', length=10) }}" - test_resource_prefix: ab-02 - - module_defaults: - group/aws: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" - region: "{{ aws_region }}" - + custom_ami_ec2_instance_type: t2.micro block: - - name: Create temporary file to store private key - ansible.builtin.tempfile: - suffix: id_rsa - register: tmpfile - - - name: Set 'keyfile_path' variable - ansible.builtin.set_fact: - keyfile_path: "{{ tmpfile.path }}" - - - name: Set 'custom_ami_name' variable - ansible.builtin.set_fact: - custom_ami_name: custom-ami-{{ test_resource_prefix }} - - # Create custom AMI - - name: Create custom AMI - ansible.builtin.include_tasks: create.yml - - # Create EC2 instance using custom AMI - - name: Create EC2 instance using custom AMI - ansible.builtin.include_tasks: create_infra.yml + # Test: create custom AMI + - name: Create AMI with initial settings + ansible.builtin.include_role: + name: cloud.aws_ops.customized_ami vars: - ec2_instance_name: ec2_initial - - # Test podman on running instance - - name: Ensure Podman is installed into EC2 instance - ansible.builtin.command: podman pull docker.io/nginx - delegate_to: ec2_initial - changed_when: false + custom_ami_packages: + - podman - # Update custom AMI + - name: Validate settings for initial AMI + vars: + ami_ec2_instance_name: "ec2-initial" + block: + - name: Create EC2 instance using custom AMI + ansible.builtin.include_tasks: create_infra.yml + + - name: Ensure Podman is installed into EC2 instance + ansible.builtin.command: podman pull docker.io/nginx + delegate_to: "{{ ami_ec2_instance_name }}" + become: true + changed_when: false + + # Test: update custom AMI - name: Update custom AMI - ansible.builtin.include_tasks: update.yml - - # Create another EC2 instance using updated custom AMI - - name: Create another EC2 instance using updated custom AMI - ansible.builtin.include_tasks: create_infra.yml + ansible.builtin.include_role: + name: cloud.aws_ops.customized_ami vars: - ec2_instance_name: ec2_updated + custom_ami_packages: + - libvirt + custom_ami_recreate_if_exists: true - # Test podman on running instance - - name: Ensure Podman is installed into EC2 instance - ansible.builtin.command: podman pull docker.io/nginx - ignore_errors: true - register: podman - delegate_to: ec2_updated - changed_when: false - - - name: Validate that Podman is not installed - ansible.builtin.assert: - that: - - podman is failed - - - name: Start libvirt service on EC2 instance - ansible.builtin.service: - name: libvirtd - state: started - delegate_to: ec2_updated - become: true - - # Delete custom AMI - - name: Delete custom AMI - ansible.builtin.include_tasks: delete.yml + - name: Validate settings for updated AMI + vars: + ami_ec2_instance_name: "ec2-updated" + block: + - name: Create EC2 instance using custom AMI + ansible.builtin.include_tasks: create_infra.yml + + - name: Trying to run Podman + ansible.builtin.command: podman pull docker.io/nginx + ignore_errors: true + register: __result + delegate_to: "{{ ami_ec2_instance_name }}" + become: true + changed_when: false + + - name: Validate that Podman is not installed + ansible.builtin.assert: + that: + - __result is failed + + - name: Start libvirt service on EC2 instance + ansible.builtin.service: + name: libvirtd + state: started + delegate_to: "{{ ami_ec2_instance_name }}" + become: true + + # Test: delete custom AMI + - name: Delete customized AMI + ansible.builtin.include_role: + name: cloud.aws_ops.customized_ami + vars: + custom_ami_operation: delete - name: Get custom AMI information amazon.aws.ec2_ami_info: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" filters: name: "{{ custom_ami_name }}" - register: ami_info + register: __amis - name: Ensure Custom AMI was deleted ansible.builtin.assert: that: - - ami_info.images | length == 0 + - __amis.images | length == 0 always: - name: Include 'delete_infra.yml' file ansible.builtin.include_tasks: delete_infra.yml - - name: Delete temporary file - ansible.builtin.file: - path: "{{ keyfile_path }}" - state: absent - when: keyfile_path is defined - ignore_errors: true + - name: Delete customized AMI + ansible.builtin.include_role: + name: cloud.aws_ops.customized_ami + vars: + custom_ami_operation: delete diff --git a/tests/integration/targets/test_customized_ami/tasks/update.yml b/tests/integration/targets/test_customized_ami/tasks/update.yml deleted file mode 100644 index 0eb7735a..00000000 --- a/tests/integration/targets/test_customized_ami/tasks/update.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- name: Include 'customized_ami' role - ansible.builtin.include_role: - name: cloud.aws_ops.customized_ami - vars: - custom_ami_packages: "{{ ami_update_packages }}" - custom_ami_recreate_if_exists: true diff --git a/tests/integration/targets/test_ec2_instance_terminate_by_tag/aliases b/tests/integration/targets/test_ec2_instance_terminate_by_tag/aliases new file mode 100644 index 00000000..c8d67dac --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_terminate_by_tag/aliases @@ -0,0 +1,3 @@ +cloud/aws +role/ec2_instance_terminate_by_tag +time=3m \ No newline at end of file diff --git a/tests/integration/targets/test_ec2_instance_terminate_by_tag/defaults/main.yml b/tests/integration/targets/test_ec2_instance_terminate_by_tag/defaults/main.yml new file mode 100644 index 00000000..7c9f88f9 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_terminate_by_tag/defaults/main.yml @@ -0,0 +1,12 @@ +--- +aws_security_token: '{{ security_token | default(omit) }}' +test_vpc_name: 'vpc-{{ resource_prefix }}' +test_vpc_cidr: '101.{{ 255 | random(seed=resource_prefix) }}.0.0/16' +test_subnet_cidr: '101.{{ 255 | random(seed=resource_prefix) }}.0.0/24' +ec2_instances: + - name: "ec2-{{ resource_prefix }}-1" + tags: + resource_prefix: "test-ec2-terminate-instance-by-tag-{{ resource_prefix }}-1" + - name: "ec2-{{ resource_prefix }}-2" + tags: + resource_prefix: "test-ec2-terminate-instance-by-tag-{{ resource_prefix }}-2" diff --git a/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/ensure_instance.yml b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/ensure_instance.yml new file mode 100644 index 00000000..1bb9bfb7 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/ensure_instance.yml @@ -0,0 +1,21 @@ +--- +- name: Ensure instance + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: Get EC2 instances info + amazon.aws.ec2_instance_info: + filters: + instance-state-name: running + vpc-id: "{{ test_vpc_id }}" + 'tag:Name': "{{ item.name }}" + register: instances + + - name: Ensure number of instances + ansible.builtin.assert: + that: + - instances.instances | length == item.instances diff --git a/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/main.yml b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/main.yml new file mode 100644 index 00000000..680acdea --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/main.yml @@ -0,0 +1,50 @@ +--- +- name: Test Role 'ec2_instance_terminate_by_tag' + block: + - name: Create EC2 instances + ansible.builtin.include_tasks: setup.yml + + - name: Delete first instance by tag + ansible.builtin.include_role: + name: cloud.aws_ops.ec2_instance_terminate_by_tag + vars: + tag_key_to_terminate_instances: "{{ ec2_instances.0.tags.keys() | first }}" + tag_value_to_terminate_instances: "{{ ec2_instances.0.tags.values() | first }}" + + - name: Validate that first instance was deleted and second still exists + ansible.builtin.include_tasks: ensure_instance.yml + with_items: + - name: "{{ ec2_instances.0.name }}" + instances: 0 + - name: "{{ ec2_instances.1.name }}" + instances: 1 + + - name: Try to delete instance with a valid tag key but wrong tag value + ansible.builtin.include_role: + name: cloud.aws_ops.ec2_instance_terminate_by_tag + vars: + tag_key_to_terminate_instances: "{{ ec2_instances.1.tags.keys() | first }}" + tag_value_to_terminate_instances: "{{ ec2_instances.0.tags.values() | first }}" + + - name: Ensure second instance was not deleted + ansible.builtin.include_tasks: ensure_instance.yml + with_items: + - name: "{{ ec2_instances.1.name }}" + instances: 1 + + - name: Delete second instance using the right key/value tag + ansible.builtin.include_role: + name: cloud.aws_ops.ec2_instance_terminate_by_tag + vars: + tag_key_to_terminate_instances: "{{ ec2_instances.1.tags.keys() | first }}" + tag_value_to_terminate_instances: "{{ ec2_instances.1.tags.values() | first }}" + + - name: Ensure second instance was not deleted + ansible.builtin.include_tasks: ensure_instance.yml + with_items: + - name: "{{ ec2_instances.1.name }}" + instances: 0 + + always: + - name: Delete EC2 instances + ansible.builtin.include_tasks: teardown.yml diff --git a/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/setup.yml b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/setup.yml new file mode 100644 index 00000000..45a4ec1c --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/setup.yml @@ -0,0 +1,59 @@ +--- +- name: Setup + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: Get source AMI image ID using filters + amazon.aws.ec2_ami_info: + filters: + architecture: x86_64 + virtualization-type: hvm + root-device-type: ebs + name: Fedora-Cloud-Base-37-* + register: images + # very spammy + no_log: true + + - name: Create vpc to work in + amazon.aws.ec2_vpc_net: + cidr_block: "{{ test_vpc_cidr }}" + name: "{{ test_vpc_name }}" + state: present + register: vpc + + - name: Define VPC id + ansible.builtin.set_fact: + test_vpc_id: "{{ vpc.vpc.id }}" + + - name: Create EC2 subnet + amazon.aws.ec2_vpc_subnet: + vpc_id: "{{ test_vpc_id }}" + cidr: "{{ test_subnet_cidr }}" + register: subnet + + - name: Create a virtual machine + amazon.aws.ec2_instance: + name: "{{ item.name }}" + instance_type: "t2.micro" + image_id: "{{ images.images.0.image_id }}" + wait: false + subnet_id: "{{ subnet.subnet.id }}" + state: started + network: + assign_public_ip: false + tags: "{{ item.tags | combine({'Name': item.name}) }}" + with_items: "{{ ec2_instances }}" + + - name: Wait until instances are running + amazon.aws.ec2_instance_info: + filters: + vpc-id: "{{ test_vpc_id }}" + instance-state-name: running + register: instances + retries: 30 + delay: 10 + until: instances.instances | length == 2 diff --git a/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/teardown.yml b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/teardown.yml new file mode 100644 index 00000000..e3c45911 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_terminate_by_tag/tasks/teardown.yml @@ -0,0 +1,32 @@ +--- +- name: Teardown + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: List existing instances + amazon.aws.ec2_instance_info: + filters: + vpc-id: "{{ test_vpc_id }}" + register: instances + + - name: Delete EC2 instances + amazon.aws.ec2_instance: + instance_ids: "{{ instances.instances | map(attribute='instance_id') | list }}" + wait: true + state: absent + + - name: Delete Subnets + amazon.aws.ec2_vpc_subnet: + vpc_id: "{{ test_vpc_id }}" + cidr: "{{ test_subnet_cidr }}" + state: absent + + - name: Delete a VPC + amazon.aws.ec2_vpc_net: + cidr_block: "{{ test_vpc_cidr }}" + vpc_id: "{{ test_vpc_id }}" + state: absent diff --git a/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/aliases b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/aliases new file mode 100644 index 00000000..b2fed518 --- /dev/null +++ b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/aliases @@ -0,0 +1,4 @@ +cloud/aws +role/enable_cloudtrail_encryption_with_kms +time=30s +disabled # reason: missing policies 'cloudtrail:DescribeTrails' and 'cloudtrail:CreateTrail' \ No newline at end of file diff --git a/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/defaults/main.yml b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/defaults/main.yml index 4861cbf1..4bdbe74f 100644 --- a/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/defaults/main.yml +++ b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/defaults/main.yml @@ -1,2 +1,7 @@ --- # defaults file for tests/integration/targets/test_enable_cloudtrail_encryption_with_kms +aws_security_token: '{{ security_token | default(omit) }}' +s3_bucket_name: "s3-{{ resource_prefix }}" +cloudtrail_name: "trail-{{ resource_prefix }}" +kms_alias: "kms-{{ resource_prefix }}" +cloudtrail_prefix: "trail-prefix-{{ resource_prefix }}" diff --git a/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/meta/main.yml b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/meta/main.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/tasks/main.yml b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/tasks/main.yml index fba6b4fc..9f68525d 100644 --- a/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/tasks/main.yml +++ b/tests/integration/targets/test_enable_cloudtrail_encryption_with_kms/tasks/main.yml @@ -1,58 +1,42 @@ --- # tasks file for tests/integration/targets/test_enable_cloudtrail_encryption_with_kms - -- name: Set 'test_resource_prefix' variable - ansible.builtin.set_fact: - test_resource_prefix: ansible-cloudtrail-{{ 101 | random(1, 10) }} - - name: Integration tests for 'enable_cloudtrail_encryption_with_kms' role - module_defaults: - group/aws: - aws_access_key: "{{ aws_access_key }}" - aws_secret_key: "{{ aws_secret_key }}" - security_token: "{{ security_token | default(omit) }}" - region: "{{ aws_region }}" - block: - - name: Set 's3_bucket_name', 'cloudtrail_name', 'kms_alias' and 'cloudtrail_prefix' variables - ansible.builtin.set_fact: - s3_bucket_name: s3-{{ test_resource_prefix }} - cloudtrail_name: trail-{{ test_resource_prefix }} - kms_alias: kms-{{ test_resource_prefix }} - cloudtrail_prefix: asible-test-prefix - - - name: Create S3 bucket - amazon.aws.s3_bucket: - state: present - name: "{{ s3_bucket_name }}" - policy: '{{ lookup("template", "s3-policy.j2") }}' - - - name: Create KMS Key - amazon.aws.aws_kms: - state: present - alias: "{{ kms_alias }}" - enabled: true - policy: "{{ lookup('template', 'kms-policy.j2') | to_json }}" - register: __create_kms_key + - name: Setup environment for test + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: Create S3 bucket + amazon.aws.s3_bucket: + state: present + name: "{{ s3_bucket_name }}" + policy: '{{ lookup("template", "s3-policy.j2") }}' - - name: Set 'kms_key_id' variable - ansible.builtin.set_fact: - kms_key_id: __create_kms_key.key_id + - name: Create KMS Key + amazon.aws.kms_key: + state: present + alias: "{{ kms_alias }}" + enabled: true + policy: "{{ lookup('template', 'kms-policy.j2') | to_json }}" - - name: Create a trail - amazon.aws.cloudtrail: - state: present - name: "{{ cloudtrail_name }}" - s3_bucket_name: "{{ s3_bucket_name }}" - s3_key_prefix: "{{ cloudtrail_prefix }}" - register: __create_trail + - name: Create a trail + amazon.aws.cloudtrail: + state: present + name: "{{ cloudtrail_name }}" + s3_bucket_name: "{{ s3_bucket_name }}" + s3_key_prefix: "{{ cloudtrail_prefix }}" + register: __create_trail - - name: Assert that trail has been created - ansible.builtin.assert: - that: - - __create_trail is changed - - __create_trail.exists == True - - __create_trail.trail.name == cloudtrail_name + - name: Assert that trail has been created + ansible.builtin.assert: + that: + - __create_trail is changed + - __create_trail.exists | bool + - __create_trail.trail.name == cloudtrail_name - name: Include 'enable_cloudtrail_encryption_with_kms' role ansible.builtin.include_role: @@ -62,21 +46,29 @@ enable_cloudtrail_encryption_with_kms_kms_key_id: "{{ kms_alias }}" always: - - name: Delete trail - amazon.aws.cloudtrail: - state: absent - name: "{{ cloudtrail_name }}" - ignore_errors: true + - name: Delete resources created for test + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + block: + - name: Delete trail + amazon.aws.cloudtrail: + state: absent + name: "{{ cloudtrail_name }}" + ignore_errors: true - - name: Delete S3 bucket - amazon.aws.s3_bucket: - state: absent - name: "{{ s3_bucket_name }}" - force: true - ignore_errors: true + - name: Delete S3 bucket + amazon.aws.s3_bucket: + state: absent + name: "{{ s3_bucket_name }}" + force: true + ignore_errors: true - - name: Delete KMS Key - amazon.aws.aws_kms: - state: absent - alias: "{{ kms_alias }}" - ignore_errors: true + - name: Delete KMS Key + amazon.aws.kms_key: + state: absent + alias: "{{ kms_alias }}" + ignore_errors: true diff --git a/tox.ini b/tox.ini index 71b2c69b..4aab8522 100644 --- a/tox.ini +++ b/tox.ini @@ -16,8 +16,10 @@ commands = [testenv:ansible-lint] deps = - ansible-lint>=6.7.0 -commands = ansible-lint --profile production --format pep8 --nocolor --strict --write {toxinidir}/playbooks {toxinidir}/roles {toxinidir}/tests + ansible-lint==6.16.0 +changedir = {toxinidir} +commands = + ansible-lint [testenv:linters] deps =