Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new ec2_instance_create role #123

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8d65950
add initial functionality to create instance from basic parameters
mandar242 Nov 18, 2024
b36ce1e
add functionality to associate EIP to instance
mandar242 Nov 19, 2024
ad9e560
rename role, ansible-lint fixes
mandar242 Nov 19, 2024
0fcb621
add functionality to create and associate sg
mandar242 Nov 20, 2024
aec04dc
add functionality to create attach igw
mandar242 Nov 20, 2024
8e4aa21
update readme and arg spec
mandar242 Nov 20, 2024
a1c5631
modified based on feedback
mandar242 Nov 20, 2024
e940702
change ec2_instance_create_external_sg_rules to list of dicts
mandar242 Nov 20, 2024
88b5223
minor fixes
mandar242 Nov 20, 2024
74ee704
add integration tests
mandar242 Nov 21, 2024
0d81188
minor fix
mandar242 Nov 21, 2024
1d7bf6e
minor fixes
mandar242 Nov 21, 2024
d7b8b80
minor update
mandar242 Nov 21, 2024
c8aa0d3
minor fixes
mandar242 Nov 21, 2024
dad97f8
add functionality to associate existing sg with instane during creation
mandar242 Nov 21, 2024
e8cf01f
update param name
mandar242 Nov 21, 2024
162ac4a
update arg spec and readme
mandar242 Nov 21, 2024
68b0fe6
linter fix, newline at eof
mandar242 Nov 21, 2024
6a8ff47
add check for instance name
mandar242 Nov 22, 2024
b82fc7c
add functionality to delete role resources
mandar242 Nov 22, 2024
33f839e
update readme
mandar242 Nov 22, 2024
84cfeae
update readme
mandar242 Nov 22, 2024
35a2670
minor fixes
mandar242 Nov 22, 2024
05d4573
linter fixes
mandar242 Nov 22, 2024
2f68c4b
linter fixes
mandar242 Nov 22, 2024
ec7de80
create key pair if does not exist
mandar242 Nov 22, 2024
ca18ea3
minor fixes
mandar242 Nov 22, 2024
5c272d9
fix terminate task
mandar242 Nov 25, 2024
e464689
update logic to handle security group association
mandar242 Nov 25, 2024
839b993
update readme
mandar242 Nov 25, 2024
a913112
minor updates
mandar242 Nov 25, 2024
be8de82
sanity fix
mandar242 Nov 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions roles/ec2_instance_create/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# ec2_instance_create

A role to create an EC2 instance in AWS.
mandar242 marked this conversation as resolved.
Show resolved Hide resolved

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**: (Required)
Whether to create or delete resources using the role. Default is `create`.
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
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)
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it is stated in the ticket that the key name should be required this should be set as optional for 2 reasons:

  • sometimes user may need to create an instance without accessing it via SSH
  • In the case the role creates the key name we need to save the public key somewhere in order for the user to be able to connect to the instance

The name of the key pair to use for SSH access to the EC2 instance.

* **ec2_instance_create_vpc_subnet_id**: (Required)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter can be also optional as the instance can be created in the default subnet id if it exists

The ID of the VPC subnet in which the instance will be launched.

* **ec2_instance_create_vpc_id**: (Optional)
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
The ID of the VPC used for security group and internet gateway.
Required if `ec2_instance_create_associate_external_sg` is `true` or `ec2_instance_create_associate_igw` is `true`.

* **ec2_instance_create_external_sg_id**: (Optional)
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
The ID or name of the existing security group to be associated with EC2 instance.
Mutually exclusive with `ec2_instance_create_associate_external_sg`.

* **ec2_instance_create_tags**: (Optional)
A dictionary of tags to assign to the EC2 instance.

* **ec2_instance_create_wait_for_boot**: (Optional)
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
Whether to wait for the EC2 instance to be in the "running" state before continuing. Default is `true`.

### Optional Networking Resources

#### Elastic IP

* **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 provided VPC doesn't have an Internet Gateway (IGW) attached, please set `ec2_instance_create_associate_igw` to true to avoid failure due to VPC not having IGW attached.

* **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_associate_external_sg**: (Optional)
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
Whether to create and associate a security group with the EC2 instance for external access. Default is `false`.
If set to `true`, a security group will be created or associated with the instance.
Mutually exclusive with `ec2_instance_create_external_sg_id`.

* **ec2_instance_create_external_sg_name**: (Optional)
The name of the security group to create. 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`.

mandar242 marked this conversation as resolved.
Show resolved Hide resolved
* **ec2_instance_create_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
# 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_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

License
-------

GNU General Public License v3.0 or later

See [LICENSE](../../LICENSE) to see the full text.

Author Information
------------------

- Ansible Cloud Content Team
11 changes: 11 additions & 0 deletions roles/ec2_instance_create/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
ec2_instance_create_associate_eip: false
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
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"
119 changes: 119 additions & 0 deletions roles/ec2_instance_create/meta/argument_specs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
argument_specs:
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
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]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it supports value create and delete, the role must be renamed

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 create and associate a 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_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 a internal gateway.
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
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_external_sg_id:
description:
- The ID or name of the security group to be associated with EC2 instance.
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
3 changes: 3 additions & 0 deletions roles/ec2_instance_create/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
dependencies:
- role: cloud.aws_ops.aws_setup_credentials
101 changes: 101 additions & 0 deletions roles/ec2_instance_create/tasks/ec2_instance_create_operations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
- name: Verify exclusive parameters
block:
- name: Check for security group ID
ansible.builtin.fail:
msg: "ec2_instance_create_external_sg_id and ec2_instance_create_associate_external_sg are mutually exlcusive.
Please provide only one to either associate existing or create new sg."
when: ec2_instance_create_external_sg_id is defined and ec2_instance_create_associate_external_sg is defined and ec2_instance_create_external_sg_id != None and ec2_instance_create_associate_external_sg is true

- name: Verify that the instance and security group with same name does not exist
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
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"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot filter on state running because this is valid only if the user waits for the instance to boot

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 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 }}"
security_group: "{{ ec2_instance_create_external_sg_id | default(omit) }}"
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: Define security group
amazon.aws.ec2_security_group:
name: "{{ ec2_instance_create_external_sg_name | default('ec2_instance_create-default-external-sg') }}"
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
description: "{{ ec2_instance_create_external_sg_description | default('Security group for external access') }}"
vpc_id: "{{ ec2_instance_create_vpc_id }}"
rules: "{{ ec2_instance_create_external_sg_rules }}"
tags: "{{ ec2_instance_create_sg_tags | default(omit) }}"
register: ec2_group_creation

- name: Associate security group with EC2 instance
amazon.aws.ec2_instance:
instance_ids:
- "{{ ec2_instance.instance_ids[0] }}"
security_groups:
- "{{ ec2_instance_create_external_sg_name | default('ec2_instance_create-default-external-sg') }}"
mandar242 marked this conversation as resolved.
Show resolved Hide resolved
vpc_subnet_id: "{{ ec2_instance_create_vpc_subnet_id }}"
register: ec2_instance_associate_external_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] }}"
Loading
Loading