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

ec2_instance: add support for modifying instance metadata options #1918

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- ec2_instance - Add support for modifying metadata options of an existing instance (https://github.com/ansible-collections/amazon.aws/pull/1918).
43 changes: 43 additions & 0 deletions plugins/modules/ec2_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,46 @@ def value_wrapper(v):
return changes_to_apply


def change_instance_metadata_options(instance, params):
metadata_options_to_apply = params.get("metadata_options")

if metadata_options_to_apply is None:
return False

existing_metadata_options = camel_dict_to_snake_dict(instance.get("MetadataOptions"))

changes_to_apply = {
key: metadata_options_to_apply[key]
for key in set(existing_metadata_options) & set(metadata_options_to_apply)
if existing_metadata_options[key] != metadata_options_to_apply[key]
}

if not changes_to_apply:
return False

request_args = {
"InstanceId": instance["InstanceId"],
"HttpTokens": changes_to_apply.get("http_tokens") or existing_metadata_options.get("http_tokens"),
"HttpPutResponseHopLimit": changes_to_apply.get("http_put_response_hop_limit")
or existing_metadata_options.get("http_put_response_hop_limit"),
"HttpEndpoint": changes_to_apply.get("http_endpoint") or existing_metadata_options.get("http_endpoint"),
"HttpProtocolIpv6": changes_to_apply.get("http_protocol_ipv6")
or existing_metadata_options.get("http_protocol_ipv6"),
"InstanceMetadataTags": changes_to_apply.get("instance_metadata_tags")
or existing_metadata_options.get("instance_metadata_tags"),
}

if module.check_mode:
return True
try:
client.modify_instance_metadata_options(aws_retry=True, **request_args)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
module.fail_json_aws(
e, msg=f"Failed to update instance metadata options for instance ID: {instance['InstanceId']}"
)
return True


def change_network_attachments(instance, params):
if (params.get("network") or {}).get("interfaces") is not None:
new_ids = []
Expand Down Expand Up @@ -1959,6 +1999,9 @@ def handle_existing(existing_matches, state, filters):

for instance in existing_matches:
changed |= ensure_ec2_tags(client, module, instance["InstanceId"], tags=tags, purge_tags=purge_tags)

changed |= change_instance_metadata_options(instance, module.params)

changes = diff_instance_and_params(instance, module.params)
for c in changes:
if not module.check_mode:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@
session_token: "{{ security_token | default(omit) }}"
region: "{{ aws_region }}"
block:
- name: create t3.nano instance with metadata_options

- name: Create a new instance
amazon.aws.ec2_instance:
state: present
name: "{{ resource_prefix }}-test-t3nano-enabled-required"
state: running
name: "{{ resource_prefix }}-test-basic"
instance_type: "{{ ec2_instance_type }}"
image_id: "{{ ec2_ami_id }}"
tags:
TestId: "{{ ec2_instance_tag_TestId }}"
vpc_subnet_id: "{{ testing_subnet_a.subnet.id }}"
instance_type: t3.nano
metadata_options:
http_endpoint: enabled
http_tokens: required
instance_metadata_tags: enabled
wait: false
http_put_response_hop_limit: 2
wait: true
register: instance_creation

- name: instance with metadata_options created with the right options
Expand All @@ -31,6 +32,7 @@
- instance_creation.spec.MetadataOptions.HttpEndpoint == 'enabled'
- instance_creation.spec.MetadataOptions.HttpTokens == 'required'
- instance_creation.spec.MetadataOptions.InstanceMetadataTags == 'enabled'
- instance_creation.spec.MetadataOptions.HttpPutResponseHopLimit == 2

- name: modify metadata_options on existing instance
amazon.aws.ec2_instance:
Expand All @@ -44,22 +46,23 @@
metadata_options:
http_endpoint: enabled
http_tokens: optional
http_put_response_hop_limit: 4
wait: false
register: metadata_options_update
ignore_errors: true

- name: fact presented ec2 instance
amazon.aws.ec2_instance_info:
filters:
tag:Name: "{{ resource_prefix }}-test-t3nano-enabled-required"
register: presented_instance_fact

- name: modify metadata_options has no effect on existing instance
- name: Assert that instance metadata options have been modified successfully
ansible.builtin.assert:
that:
- metadata_options_update is success
- metadata_options_update is not changed
- metadata_options_update is changed
- presented_instance_fact.instances | length > 0
- presented_instance_fact.instances.0.state.name in ['running','pending']
- presented_instance_fact.instances.0.metadata_options.http_endpoint == 'enabled'
- presented_instance_fact.instances.0.metadata_options.http_tokens == 'required'
- presented_instance_fact.instances.0.metadata_options.http_tokens == 'optional'
- presented_instance_fact.instances.0.metadata_options.http_put_response_hop_limit == 4
Loading