diff --git a/roles/ec2_instance_create/README.md b/roles/ec2_instance_create/README.md new file mode 100644 index 0000000..133cd0d --- /dev/null +++ b/roles/ec2_instance_create/README.md @@ -0,0 +1,157 @@ +# ec2_instance_create + +A role to create an EC2 instance in AWS. + +Users can specify various parameters for instance configuration, including instance type, AMI ID, key pair, tags, and VPC/subnet configuration. + +This role also supports the creation of optional networking resources, such as an external security group and an Elastic IP (EIP). You can choose to wait for the EC2 instance to finish booting before continuing. + +## Role Variables + +The following variables can be set in the role to customize EC2 instance creation and networking configurations: + +### Role Operation + +* **ec2_instance_create_operation**: (Optional) + Whether to create or delete resources using the role. Default is `create`. + Choices are `create` and `delete`. + +### EC2 Instance Configuration + +* **ec2_instance_create_aws_region**: (Required) + The AWS region in which to create the EC2 instance. + +* **ec2_instance_create_instance_name**: (Required) + The name of the EC2 instance to be created. + +* **ec2_instance_create_instance_type**: (Required) + The instance type for the EC2 instance (e.g., `t2.micro`, `m5.large`). + +* **ec2_instance_create_ami_id**: (Required) + The AMI ID for the EC2 instance. + +* **ec2_instance_create_key_name**: (Required) + The name of the key pair to use for SSH access to the EC2 instance. + If the key does not exist, a key pair will be created with the name. + +* **ec2_instance_create_vpc_subnet_id**: (Required) + The ID of the VPC subnet in which the instance will be launched. + +* **ec2_instance_create_tags**: (Optional) + A dictionary of tags to assign to the EC2 instance. + +* **ec2_instance_create_wait_for_boot**: (Optional) + Whether to wait for the EC2 instance to be in the "running" or "terminated" state before continuing. Default is `true`. + +### Optional Networking Resources + +#### Elastic IP + +* **ec2_instance_create_vpc_id**: (Optional) + The ID of the VPC used for security group and internet gateway. + Required if `ec2_instance_create_associate_igw` or `ec2_instance_create_associate_eip` is `true`. + +* **ec2_instance_create_associate_eip**: (Optional) + Whether to create an Elastic IP (EIP) and associate it with the EC2 instance. Default is `false`. + If set to `true` and the provided VPC doesn't have an Internet Gateway (IGW) attached, set `ec2_instance_create_associate_igw` to `true` to avoid failure. + +* **ec2_instance_create_eip_tags**: (Optional) + Tags to assign to the elastic IP. + +#### Internet Gateway + +* **ec2_instance_create_associate_igw**: (Optional) + Whether to create and associate an internet gateway with the EC2 instance. Default is `false`. + If set to `true`, an internet gateway will be created or associated with the instance. + +* **ec2_instance_create_igw_tags**: (Optional) + Tags to assign to the internet gateway. + +#### External Security Group + +* **ec2_instance_create_external_sg_name**: (Required) + The name of the security group to use for the EC2 instance. + The role will check if an SG with this name exists. If not, it will create a new one. + Default is `ec2_instance_create-default-external-sg`. + +* **ec2_instance_create_external_sg_description**: (Optional) + A description for the security group. Default is `Security group for external access`. + +* **ec2_instance_create_external_sg_rules**: (Optional) + A list of custom rules to add to the security group. Each rule is a dictionary with `proto`, `ports`, and `cidr_ip` keys. Default is to allow SSH (port 22) from `0.0.0.0/0`. + +* **ec2_instance_create_external_sg_tags**: (Optional) + Tags to assign to the security group. + +### Example: + +Here's an example of how to use the role in a playbook. + +```yaml +--- +- name: Playbook for creating EC2 instance using cloud.aws_ops.ec2_instance_create role + hosts: localhost + gather_facts: false + roles: + - role: cloud.aws_ops.ec2_instance_create + vars: + ec2_instance_create_operation: create + ec2_instance_create_aws_region: us-west-2 + ec2_instance_create_instance_name: my-test-instance + ec2_instance_create_instance_type: t2.micro + ec2_instance_create_ami_id: ami-066a7fbaa12345678 + ec2_instance_create_vpc_subnet_id: subnet-071443aa123456789 + ec2_instance_create_tags: + Component: my-test-instance + Environment: Testing + ec2_instance_create_wait_for_boot: true + ec2_instance_create_vpc_id: vpc-xxxx + # Optionally, enable security group creation + ec2_instance_create_associate_external_sg: true + ec2_instance_create_external_sg_name: my-custom-sg + ec2_instance_create_external_sg_description: Security group for my custom access + ec2_instance_create_external_sg_rules: + - proto: tcp + ports: "80" + cidr_ip: "0.0.0.0/0" + ec2_instance_create_external_sg_tags: + Component: my-custom-sg + Environment: Testing + # Optionally, enable Elastic IP association + ec2_instance_create_associate_eip: true + ec2_instance_create_eip_tags: + Component: my-custom-eip + Environment: Testing + # Optionally, enable Internet Gateway association + ec2_instance_create_associate_igw: true + ec2_instance_create_igw_tags: + Environment: Testing + Name: "{{ resource_prefix }}-igw" + +--- +- name: Playbook for deleting EC2 instance and other role resources using cloud.aws_ops.ec2_instance_create role + hosts: localhost + gather_facts: false + roles: + - role: cloud.aws_ops.ec2_instance_create + vars: + ec2_instance_create_operation: delete + ec2_instance_create_aws_region: us-west-2 + ec2_instance_create_instance_name: my-test-instance + ec2_instance_create_wait_for_boot: true + ec2_instance_create_associate_external_sg: true + ec2_instance_create_external_sg_name: my-custom-sg + ec2_instance_create_associate_igw: true + ec2_instance_create_vpc_id: vpc-xxxx + +License +------- + +GNU General Public License v3.0 or later + +See [LICENSE](../../LICENSE) to see the full text. + +Author Information +------------------ + +- Ansible Cloud Content Team diff --git a/roles/ec2_instance_create/defaults/main.yml b/roles/ec2_instance_create/defaults/main.yml new file mode 100644 index 0000000..1a9bad1 --- /dev/null +++ b/roles/ec2_instance_create/defaults/main.yml @@ -0,0 +1,12 @@ +--- +ec2_instance_create_operation: create +ec2_instance_create_associate_eip: false +ec2_instance_create_associate_external_sg: false +ec2_instance_create_associate_igw: false +ec2_instance_create_external_sg_description: "Security group for external access" +ec2_instance_create_external_sg_name: "ec2_instance_create-default-external-sg" +ec2_instance_create_wait_for_boot: true +ec2_instance_create_external_sg_rules: + - proto: tcp + ports: "22" + cidr_ip: "0.0.0.0/0" diff --git a/roles/ec2_instance_create/meta/argument_specs.yml b/roles/ec2_instance_create/meta/argument_specs.yml new file mode 100644 index 0000000..10cdbb4 --- /dev/null +++ b/roles/ec2_instance_create/meta/argument_specs.yml @@ -0,0 +1,114 @@ +--- +argument_specs: + main: + short_description: A role to create an EC2 instance with optional networking resources. + description: + - A role to create an EC2 instance. + - Optionally can create a security group and associate an Elastic IP with the instance. + - Supports custom configurations for instance settings, including instance type, AMI, key pair, tags, VPC/subnet, and networking configurations. + options: + ec2_instance_create_operation: + description: + - Whether to create or delete resources using the role. + required: false + type: str + default: create + choices: [create, delete] + ec2_instance_create_aws_region: + description: + - The AWS region in which to create the EC2 instance. + required: true + type: str + ec2_instance_create_instance_name: + description: + - The name of the EC2 instance to be created. + required: true + type: str + ec2_instance_create_instance_type: + description: + - The instance type for the EC2 instance. + required: true + type: str + ec2_instance_create_ami_id: + description: + - The AMI ID for the EC2 instance. + required: true + type: str + ec2_instance_create_key_name: + description: + - The name of the key pair to use for SSH access to the EC2 instance. + required: true + type: str + ec2_instance_create_vpc_subnet_id: + description: + - The ID of the VPC subnet in which the instance will be launched. + required: true + type: str + ec2_instance_create_tags: + description: + - A dictionary of tags to assign to the EC2 instance. + required: false + type: dict + ec2_instance_create_wait_for_boot: + description: + - Whether to wait for the EC2 instance to be in the running state before continuing. + required: false + default: true + type: bool + ec2_instance_create_associate_eip: + description: + - Whether to create and associate an Elastic IP (EIP) with the EC2 instance. + required: false + default: false + type: bool + ec2_instance_create_associate_external_sg: + description: + - Whether to associate an existing or a new security group for external access. + required: false + default: false + type: bool + ec2_instance_create_external_sg_name: + description: + - The name of the security group to create. + required: false + default: "ec2_instance_create-default-external-sg" + type: str + ec2_instance_create_external_sg_description: + description: + - A description of the security group. + required: false + default: "Security group for external access" + type: str + ec2_instance_create_external_sg_tags: + description: + - Tags to assign to the security group. + required: false + type: dict + ec2_instance_create_associate_igw: + description: + - Whether to create and associate an internal gateway. + required: false + default: false + type: bool + ec2_instance_create_vpc_id: + description: + - The ID of the VPC used for security group and internet gateway. + - This is required when `ec2_instance_create_associate_external_sg` or `ec2_instance_create_associate_igw` is `true`. + required: false + type: str + ec2_instance_create_eip_tags: + description: + - Tags to assign to the Elastic IP. + required: false + type: dict + ec2_instance_create_external_sg_rules: + description: + - A list of dict containing custom rules to add to the security group. Each rule is a dictionary with `proto`, `ports`, and `cidr_ip` keys. Default is to allow SSH (port 22) from `0.0.0.0/0`. + required: false + type: list + elements: dict + ec2_instance_create_igw_tags: + description: + - Tags to assign to the internet gateway. + required: false + type: dict diff --git a/roles/ec2_instance_create/meta/main.yml b/roles/ec2_instance_create/meta/main.yml new file mode 100644 index 0000000..e8b3ab4 --- /dev/null +++ b/roles/ec2_instance_create/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: cloud.aws_ops.aws_setup_credentials diff --git a/roles/ec2_instance_create/tasks/ec2_instance_create_operations.yml b/roles/ec2_instance_create/tasks/ec2_instance_create_operations.yml new file mode 100644 index 0000000..13022d3 --- /dev/null +++ b/roles/ec2_instance_create/tasks/ec2_instance_create_operations.yml @@ -0,0 +1,115 @@ +--- +- name: Verify that an instance with same name does not exist + block: + - name: Get instane info with provided name + amazon.aws.ec2_instance_info: + region: "{{ ec2_instance_create_aws_region }}" + filters: + tag:Name: "{{ ec2_instance_create_instance_name }}" + instance-state-name: ["running"] + register: ec2_info_result + + - name: Print warning and exit + ansible.builtin.fail: + msg: "Instance with name {{ ec2_instance_create_instance_name }} already exists in {{ ec2_instance_create_aws_region }}. + Please provide different name to avoid updating instance." + when: ec2_info_result.instances | length >= 1 + +- name: Create a key pair if required + block: + - name: Get key pair info + amazon.aws.ec2_key_info: + names: + - "{{ ec2_instance_create_key_name }}" + register: key_info_result + + - name: Create new key pair + amazon.aws.ec2_key: + name: "{{ ec2_instance_create_key_name }}" + state: present + region: "{{ ec2_instance_create_aws_region }}" + when: key_info_result.keypairs | length == 0 + +- name: Create EC2 instance with provided configuration + amazon.aws.ec2_instance: + region: "{{ ec2_instance_create_aws_region }}" + name: "{{ ec2_instance_create_instance_name }}" + instance_type: "{{ ec2_instance_create_instance_type }}" + image_id: "{{ ec2_instance_create_ami_id }}" + key_name: "{{ ec2_instance_create_key_name }}" + vpc_subnet_id: "{{ ec2_instance_create_vpc_subnet_id }}" + tags: "{{ ec2_instance_create_tags | default(omit) }}" + wait: "{{ ec2_instance_create_wait_for_boot }}" + register: ec2_instance + +- name: Create security group if enabled + when: ec2_instance_create_associate_external_sg is true + block: + - name: Get SG info + amazon.aws.ec2_security_group_info: + region: "{{ ec2_instance_create_aws_region }}" + filters: + group-name: "{{ ec2_instance_create_external_sg_name }}" + register: sg_info_result + + - name: Create a new SG if it does not exist + amazon.aws.ec2_security_group: + name: "{{ ec2_instance_create_external_sg_name }}" + description: "{{ ec2_instance_create_external_sg_description }}" + vpc_id: "{{ ec2_instance_create_vpc_id }}" + rules: "{{ ec2_instance_create_external_sg_rules }}" + tags: "{{ ec2_instance_create_external_sg_tags | default(omit) }}" + when: sg_info_result.security_groups | length == 0 + register: sg_creation + + - name: Associate the SG to EC2 Instance(existing or newly created) + amazon.aws.ec2_instance: + instance_ids: + - "{{ ec2_instance.instance_ids[0] }}" + security_groups: + - "{{ ec2_instance_create_external_sg_name }}" + vpc_subnet_id: "{{ ec2_instance_create_vpc_subnet_id }}" + register: ec2_instance_associate_sg + +- name: Create and Attach Internet Gateway if enabled + when: ec2_instance_create_associate_igw is true + block: + - name: Create an Internet Gateway + amazon.aws.ec2_vpc_igw: + region: "{{ ec2_instance_create_aws_region }}" + vpc_id: "{{ ec2_instance_create_vpc_id }}" + state: present + tags: "{{ ec2_instance_create_igw_tags | default(omit) }}" + register: internet_gateway + + - name: Modify the route table to route internet traffic to Internet Gateway + amazon.aws.ec2_vpc_route_table: + region: "{{ ec2_instance_create_aws_region }}" + vpc_id: "{{ ec2_instance_create_vpc_id }}" + routes: + - dest: "0.0.0.0/0" + gateway_id: "{{ internet_gateway.gateway_id }}" + state: present + +- name: Create and associate Elastic IP if enabled + when: ec2_instance_create_associate_eip is true + block: + - name: Allocate and associate Elastic IP + amazon.aws.ec2_eip: + device_id: "{{ ec2_instance.instance_ids[0] }}" + state: present + release_on_disassociation: true + tags: "{{ ec2_instance_create_eip_tags | default(omit) }}" + register: instance_eip + +- name: Get EC2 instance info + amazon.aws.ec2_instance_info: + instance_ids: "{{ ec2_instance.instance_ids[0] }}" + region: "{{ ec2_instance_create_aws_region }}" + register: _ec2_instance + +- name: Output details of the created EC2 instance + ansible.builtin.debug: + msg: + - "EC2 instance {{ ec2_instance.instance_ids[0] }} created successfully" + - "Instance details: {{ _ec2_instance.instances[0] }}" diff --git a/roles/ec2_instance_create/tasks/ec2_instance_delete_operations.yml b/roles/ec2_instance_create/tasks/ec2_instance_delete_operations.yml new file mode 100644 index 0000000..ddffbcc --- /dev/null +++ b/roles/ec2_instance_create/tasks/ec2_instance_delete_operations.yml @@ -0,0 +1,23 @@ +--- +- name: Terminate EC2 Instance + amazon.aws.ec2_instance: + region: "{{ ec2_instance_create_aws_region }}" + state: absent + wait: "{{ ec2_instance_create_wait_for_boot }}" + filters: + tag:Name: "{{ ec2_instance_create_instance_name }}" + instance-state-name: ["running"] + when: ec2_instance_create_instance_name is defined and ec2_instance_create_instance_name | length > 0 + +- name: Delete security group if created + amazon.aws.ec2_security_group: + name: "{{ ec2_instance_create_external_sg_name | default('ec2_instance_create-default-external-sg') }}" + state: absent + when: ec2_instance_create_associate_external_sg is defined and ec2_instance_create_associate_external_sg is true + +- name: Detach and delete Internet Gateway if created + amazon.aws.ec2_vpc_igw: + region: "{{ ec2_instance_create_aws_region }}" + vpc_id: "{{ ec2_instance_create_vpc_id }}" + state: absent + when: ec2_instance_create_associate_igw is defined and ec2_instance_create_associate_igw is true diff --git a/roles/ec2_instance_create/tasks/main.yml b/roles/ec2_instance_create/tasks/main.yml new file mode 100644 index 0000000..fb90b1c --- /dev/null +++ b/roles/ec2_instance_create/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: EC2 Instance creation or deletion based on operation + module_defaults: + group/aws: "{{ aws_setup_credentials__output }}" + block: + - name: Include create operations + ansible.builtin.include_tasks: ec2_instance_create_operations.yml + when: ec2_instance_create_operation == 'create' + + - name: Include delete operations + ansible.builtin.include_tasks: ec2_instance_delete_operations.yml + when: ec2_instance_create_operation == 'delete' diff --git a/tests/integration/targets/test_ec2_instance_create/aliases b/tests/integration/targets/test_ec2_instance_create/aliases new file mode 100644 index 0000000..5f4238a --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/aliases @@ -0,0 +1,2 @@ +cloud/aws +role/ec2_instance_create diff --git a/tests/integration/targets/test_ec2_instance_create/defaults/main.yml b/tests/integration/targets/test_ec2_instance_create/defaults/main.yml new file mode 100644 index 0000000..48e8066 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/defaults/main.yml @@ -0,0 +1,15 @@ +--- +aws_security_token: "{{ security_token | default(omit) }}" + +# VPC and Subnet Configuration +vpc_name: "{{ resource_prefix }}-vpc" +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 Instance Configuration +ec2_instance_type: t2.micro +ec2_key_name: "{{ resource_prefix }}-ec2-key" + +# External Security Group Configuration +external_sg_name: "{{ resource_prefix }}-external-sg" +external_sg_description: "External Security Group for EC2" diff --git a/tests/integration/targets/test_ec2_instance_create/tasks/main.yml b/tests/integration/targets/test_ec2_instance_create/tasks/main.yml new file mode 100644 index 0000000..d85867d --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: Integration tests for ec2_networking_resources 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: Create resources required for test + ansible.builtin.include_tasks: setup.yml + + - name: Run tests for case 1 - EC2 with no external sg, igw, eip + ansible.builtin.include_tasks: tasks/test_ec2_only.yml + + - name: Run tests for case 2 - EC2 with external sg, igw, eip + ansible.builtin.include_tasks: tasks/test_ec2_with_igw_sg_eip.yml + + always: + - name: Delete any leftover resources used in tests + ansible.builtin.include_tasks: teardown.yml diff --git a/tests/integration/targets/test_ec2_instance_create/tasks/setup.yml b/tests/integration/targets/test_ec2_instance_create/tasks/setup.yml new file mode 100644 index 0000000..cfb29c2 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/tasks/setup.yml @@ -0,0 +1,49 @@ +--- +- name: Setup + block: + - name: Get AMI image ID using filters + amazon.aws.ec2_ami_info: + region: "{{ aws_region }}" + filters: + architecture: x86_64 + # CentOS Community Platform Engineering (CPE) + owner-id: "125523088429" + virtualization-type: hvm + root-device-type: ebs + name: Fedora-Cloud-Base-* + register: images + # very spammy + no_log: true + + - name: Create vpc to work in + amazon.aws.ec2_vpc_net: + cidr_block: "{{ test_vpc_cidr }}" + name: "{{ vpc_name }}" + state: present + region: "{{ aws_region }}" + 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 }}" + az: "{{ aws_region }}a" + region: "{{ aws_region }}" + register: subnet + + - name: Create a key + amazon.aws.ec2_key: + name: "{{ ec2_key_name }}" + state: present + region: "{{ aws_region }}" + register: ec2_key_result + + - name: Set facts for test resources + ansible.builtin.set_fact: + image_id: "{{ images.images.0.image_id }}" + subnet_id: "{{ subnet.subnet.id }}" + vpc_id: "{{ vpc.vpc.id }}" diff --git a/tests/integration/targets/test_ec2_instance_create/tasks/teardown.yml b/tests/integration/targets/test_ec2_instance_create/tasks/teardown.yml new file mode 100644 index 0000000..de56330 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/tasks/teardown.yml @@ -0,0 +1,45 @@ +--- +- name: Teardown + block: + - name: Delete Subnets + amazon.aws.ec2_vpc_subnet: + vpc_id: "{{ test_vpc_id }}" + cidr: "{{ test_subnet_cidr }}" + region: "{{ aws_region }}" + state: absent + ignore_errors: true + + - name: Get list of route tables in VPC + amazon.aws.ec2_vpc_route_table_info: + region: "{{ aws_region }}" + filters: + vpc-id: "{{ vpc_id }}" + register: route_tables + + - name: Delete route tables associated with VPC + amazon.aws.ec2_vpc_route_table: + region: "{{ region }}" + route_table_id: "{{ item.route_table_id }}" + state: absent + loop: "{{ route_tables.route_tables }}" + when: route_tables.route_tables | length > 0 + ignore_errors: true + + - name: Delete a VPC + amazon.aws.ec2_vpc_net: + cidr_block: "{{ test_vpc_cidr }}" + vpc_id: "{{ test_vpc_id }}" + region: "{{ aws_region }}" + state: absent + register: delete_result + ignore_errors: true + retries: 5 + delay: 5 + until: delete_result.changed + + - name: Delete a key + amazon.aws.ec2_key: + name: "{{ resource_prefix }}-ec2-key" + region: "{{ aws_region }}" + state: absent + ignore_errors: true diff --git a/tests/integration/targets/test_ec2_instance_create/tasks/test_ec2_only.yml b/tests/integration/targets/test_ec2_instance_create/tasks/test_ec2_only.yml new file mode 100644 index 0000000..293ad59 --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/tasks/test_ec2_only.yml @@ -0,0 +1,46 @@ +--- +- block: + - name: Create EC2 instance with no external SG, no IGW, no EIP + ansible.builtin.include_role: + name: cloud.aws_ops.ec2_instance_create + vars: + ec2_instance_create_operation: create + ec2_instance_create_aws_region: "{{ aws_region }}" + ec2_instance_create_instance_name: "only-ec2-{{ resource_prefix }}" + ec2_instance_create_instance_type: "{{ ec2_instance_type }}" + ec2_instance_create_ami_id: "{{ image_id }}" + ec2_instance_create_vpc_subnet_id: "{{ subnet_id }}" + ec2_instance_create_key_name: "{{ ec2_key_name }}" + ec2_instance_create_associate_external_sg: false + ec2_instance_create_associate_eip: false + ec2_instance_create_associate_igw: false + ec2_instance_create_tags: + Environment: Testing + Name: "{{ resource_prefix }}-instance" + + - name: Get EC2 instance info + amazon.aws.ec2_instance_info: + filters: + "tag:Name": "only-ec2-{{ resource_prefix }}" + register: _ec2_instance + until: _ec2_instance.instances[0].state.name == 'running' + retries: 12 + delay: 5 + + - name: Validate EC2 creation (no SG, no IGW, no EIP) + ansible.builtin.assert: + that: + - _ec2_instance.instances | length == 1 + - _ec2_instance.instances[0].state.name == 'running' + - _ec2_instance.instances[0].tags.Name == "only-ec2-{{ resource_prefix }}" + - _ec2_instance.instances[0].network_interfaces[0].groups[0].group_name == "default" + - _ec2_instance.instances[0].key_name == ec2_key_name + + # cleanup leftover resources created by role + always: + - name: Terminate EC2 instance + amazon.aws.ec2_instance: + state: absent + instance_ids: "{{ _ec2_instance.instances[0].instance_id }}" + wait: true + ignore_errors: true diff --git a/tests/integration/targets/test_ec2_instance_create/tasks/test_ec2_with_igw_sg_eip.yml b/tests/integration/targets/test_ec2_instance_create/tasks/test_ec2_with_igw_sg_eip.yml new file mode 100644 index 0000000..37c3d6a --- /dev/null +++ b/tests/integration/targets/test_ec2_instance_create/tasks/test_ec2_with_igw_sg_eip.yml @@ -0,0 +1,119 @@ +--- +- block: + - name: Create EC2 instance with external SG, IGW, EIP + ansible.builtin.include_role: + name: cloud.aws_ops.ec2_instance_create + vars: + ec2_instance_create_operation: create + ec2_instance_create_aws_region: "{{ aws_region }}" + ec2_instance_create_instance_name: "ec2-all-enabled-{{ resource_prefix }}" + ec2_instance_create_instance_type: "{{ ec2_instance_type }}" + ec2_instance_create_ami_id: "{{ image_id }}" + ec2_instance_create_vpc_subnet_id: "{{ subnet_id }}" + ec2_instance_create_key_name: "{{ ec2_key_name }}" + ec2_instance_create_vpc_id: "{{ vpc_id }}" + ec2_instance_create_tags: + Environment: Testing + Name: "{{ resource_prefix }}-instance" + + # Optional: external security group + ec2_instance_create_associate_external_sg: true + ec2_instance_create_external_sg_name: "{{ external_sg_name }}" + ec2_instance_create_external_sg_description: "{{ external_sg_description }}" + ec2_instance_create_external_sg_rules: + - proto: tcp + ports: 22 + cidr_ip: 10.0.1.0/16 + - proto: tcp + ports: 8000 + cidr_ip: 10.0.1.0/16 + ec2_instance_create_external_sg_tags: + Environment: Testing + Name: "{{ resource_prefix }}-sg" + + # Optional: EIP + ec2_instance_create_associate_eip: true + ec2_instance_create_eip_tags: + Environment: Testing + Name: "{{ resource_prefix }}-eip" + + # Optional: Internet Gateway + ec2_instance_create_associate_igw: true + ec2_instance_create_igw_tags: + Environment: Testing + Name: "{{ resource_prefix }}-igw" + + - name: Get EC2 instance info + amazon.aws.ec2_instance_info: + filters: + "tag:Name": "ec2-all-enabled-{{ resource_prefix }}" + register: _ec2_instance + until: _ec2_instance.instances[0].state.name == 'running' + retries: 12 + delay: 5 + + - name: Gather information about Internet Gateway + amazon.aws.ec2_vpc_igw_info: + filters: + "tag:Name": "{{ resource_prefix }}-igw" + register: igw_info + + - name: print internet gateway info + debug: + var: igw_info + + - name: Gather information about security group + amazon.aws.ec2_security_group_info: + filters: + "tag:Name": "{{ resource_prefix }}-sg" + register: sg_info + + - name: print security group info + debug: + var: sg_info + + - name: Gather information about route table + amazon.aws.ec2_vpc_route_table_info: + filters: + vpc-id: "{{ vpc_id }}" + register: rtb_info + + - name: print route table info + debug: + var: rtb_info + + - name: Validate EC2 creation (SG, IGW, EIP) + ansible.builtin.assert: + that: + - _ec2_instance.instances | length == 1 + - _ec2_instance.instances[0].state.name == 'running' + - _ec2_instance.instances[0].tags.Name == "ec2-all-enabled-{{ resource_prefix }}" + - _ec2_instance.instances[0].network_interfaces[0].groups[0].group_name == "{{ external_sg_name }}" + - _ec2_instance.instances[0].key_name == ec2_key_name + - igw_info.internet_gateways[0].attachments[0].vpc_id == "{{ vpc_id }}" + - sg_info.security_groups[0].description == "{{ external_sg_description }}" + - sg_info.security_groups[0].vpc_id == "{{ vpc_id }}" + - rtb_info.route_tables[0].vpc_id == "{{ vpc_id }}" + + + # cleanup leftover resources created by role + always: + - name: Terminate EC2 instance + amazon.aws.ec2_instance: + state: absent + instance_ids: "{{ _ec2_instance.instances[0].instance_id }}" + wait: true + ignore_errors: true + + - name: Delete Internet gateway ensuring attached VPC is correct + amazon.aws.ec2_vpc_igw: + state: absent + internet_gateway_id: "{{ igw_info.internet_gateways[0].internet_gateway_id }}" + vpc_id: "{{ vpc_id }}" + ignore_errors: true + + - name: Delete security group + amazon.aws.ec2_security_group: + group_id: "{{ sg_info.security_groups[0].group_id }}" + state: absent + ignore_errors: true