Skip to content

Commit

Permalink
ec2_ami: Add support for params BootMode, TpmSupport, UefiData (ansib…
Browse files Browse the repository at this point in the history
…le-collections#1037)

ec2_ami: Add support for params BootMode, TpmSupport, UefiData

SUMMARY
Depends-On: ansible-collections#1066

Added support for params BootMode, TpmSupport, UefiData in ec2_ami.

Fixes ansible-collections#944
ISSUE TYPE


Feature Pull Request

COMPONENT NAME

ec2_ami
ADDITIONAL INFORMATION



Example playbook
- name: abc
  hosts: localhost
  gather_facts: false
  tasks:
    - name: AMI Creation with boot_mode and tpm_support
      amazon.aws.ec2_ami:
        name: ami-create-test_legacy-bios
        state: present
        architecture: x86_64
        virtualization_type: hvm
        root_device_name: /dev/sda1
        device_mapping:
          - device_name: /dev/sda1
            snapshot_id: snap-xxxxxxxxx
        wait: yes
        region: us-east-2
        boot_mode: legacy-bios
        tpm_support: v2.0
        tags:
          name: ami-create-test

Reviewed-by: Gonéri Le Bouder <[email protected]>
Reviewed-by: Mandar Kulkarni <[email protected]>
Reviewed-by: Mike Graves <[email protected]>
  • Loading branch information
mandar242 authored and alinabuzachis committed Apr 27, 2023
1 parent 67bc04d commit 9e07cec
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- ec2_ami - add support for BootMode, TpmSupport, UefiData params (https://github.com/ansible-collections/amazon.aws/pull/1037).
55 changes: 55 additions & 0 deletions plugins/modules/ec2_ami.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,27 @@
description:
- Set to simple to enable enhanced networking with the Intel 82599 Virtual Function interface for the AMI and any instances that you launch from the AMI.
type: str
boot_mode:
description:
- The boot mode of the AMI.
- See the AWS documentation for more detail U(https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ami-boot.html).
type: str
choices: ['legacy-bios', 'uefi']
tpm_support:
description:
- Set to v2.0 to enable Trusted Platform Module (TPM) support.
- If the image is configured for NitroTPM support, the value is v2.0 .
- Requires I(boot_mode) to be set to 'uefi'.
- Requires an instance type that is compatible with Nitro.
- Requires minimum botocore version 1.26.0.
- See the AWS documentation for more detail U(https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html).
type: str
uefi_data:
description:
- Base64 representation of the non-volatile UEFI variable store.
- Requires minimum botocore version 1.26.0.
- See the AWS documentation for more detail U(https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/uefi-secure-boot.html).
type: str
author:
- "Evan Duffield (@scicoin-project) <[email protected]>"
- "Constantin Bugneac (@Constantin07) <[email protected]>"
Expand Down Expand Up @@ -216,6 +237,22 @@
- device_name: /dev/sdb
no_device: true
- name: AMI Creation with boot_mode and tpm_support
amazon.aws.ec2_ami:
name: newtest
state: present
architecture: x86_64
virtualization_type: hvm
root_device_name: /dev/sda1
device_mapping:
- device_name: /dev/sda1
snapshot_id: "{{ snapshot_id }}"
wait: yes
region: us-east-1
boot_mode: uefi
uefi_data: data_file.bin
tpm_support: v2.0
- name: Deregister/Delete AMI (keep associated snapshots)
amazon.aws.ec2_ami:
image_id: "{{ instance.image_id }}"
Expand Down Expand Up @@ -441,6 +478,12 @@ def create_image(module, connection):
billing_products = module.params.get('billing_products')
ramdisk_id = module.params.get('ramdisk_id')
sriov_net_support = module.params.get('sriov_net_support')
boot_mode = module.params.get('boot_mode')
tpm_support = module.params.get('tpm_support')
uefi_data = module.params.get('uefi_data')

if tpm_support and boot_mode != 'uefi':
module.fail_json(msg="To specify 'tpm_support', 'boot_mode' must be 'uefi'.")

if module.check_mode:
image = connection.describe_images(Filters=[{'Name': 'name', 'Values': [str(name)]}])
Expand Down Expand Up @@ -509,6 +552,12 @@ def create_image(module, connection):
params['KernelId'] = kernel_id
if root_device_name:
params['RootDeviceName'] = root_device_name
if boot_mode:
params['BootMode'] = boot_mode
if tpm_support:
params['TpmSupport'] = tpm_support
if uefi_data:
params['UefiData'] = uefi_data
image_id = connection.register_image(aws_retry=True, **params).get('ImageId')
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
module.fail_json_aws(e, msg="Error registering image")
Expand Down Expand Up @@ -731,6 +780,9 @@ def main():
sriov_net_support=dict(),
tags=dict(type='dict', aliases=['resource_tags']),
purge_tags=dict(type='bool', default=True),
boot_mode=dict(type='str', choices=['legacy-bios', 'uefi']),
tpm_support=dict(type='str'),
uefi_data=dict(type='str'),
)

module = AnsibleAWSModule(
Expand All @@ -746,6 +798,9 @@ def main():
if not any([module.params['image_id'], module.params['name']]):
module.fail_json(msg="one of the following is required: name, image_id")

if any([module.params['tpm_support'], module.params['uefi_data']]):
module.require_botocore_at_least('1.26.0', reason='required for ec2.register_image with tpm_support or uefi_data')

connection = module.client('ec2', retry_decorator=AWSRetry.jittered_backoff())

if module.params.get('state') == 'absent':
Expand Down
3 changes: 3 additions & 0 deletions tests/integration/targets/ec2_ami/meta/main.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
dependencies:
- setup_ec2_facts
- role: setup_botocore_pip
vars:
botocore_version: '1.26.0'
74 changes: 74 additions & 0 deletions tests/integration/targets/ec2_ami/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
- amazon.aws
block:

# AWS CLI is needed until there's a module to get instance uefi data
- name: Install AWS CLI
pip:
name: awscli==1.25.83
state: present

# ============================================================

# SETUP: vpc, ec2 key pair, subnet, security group, ec2 instance, snapshot
Expand Down Expand Up @@ -74,6 +80,21 @@
state: present
register: setup_snapshot

# note: the current CI supported instance types (t2, t3, m1) do not support uefi boot mode + tpm_support
# disabling the task as aws documentation states that support for t3 will be coming soon
# - name: get instance UEFI data
# command: aws ec2 get-instance-uefi-data --instance-id {{ ec2_instance_id }} --region {{ aws_region }}
# environment:
# AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
# AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
# AWS_SESSION_TOKEN: "{{ security_token | default('') }}"
# AWS_DEFAULT_REGION: "{{ aws_region }}"
# register: instance_uefi_data_output

# - name: Convert it to an object
# set_fact:
# instance_uefi_data: "{{ instance_uefi_data_output.stdout | from_json }}"

# ============================================================

- name: test clean failure if not providing image_id or name with state=present
Expand Down Expand Up @@ -629,6 +650,52 @@
- not result.changed
- not result.failed

# ============================================================

- name: create an image from the snapshot with boot_mode and tpm_support
ec2_ami:
name: '{{ ec2_ami_name }}_ami-boot-tpm'
description: '{{ ec2_ami_description }}'
state: present
boot_mode: uefi
tpm_support: v2.0
launch_permissions:
user_ids: []
tags:
Name: '{{ ec2_ami_name }}_ami-boot-tpm'
root_device_name: '{{ ec2_ami_root_disk }}'
device_mapping:
- device_name: '{{ ec2_ami_root_disk }}'
volume_type: gp2
size: 8
delete_on_termination: true
snapshot_id: '{{ setup_snapshot.snapshot_id }}'
register: result
ignore_errors: true
vars:
ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}"

- name: set image id fact for deletion later
set_fact:
ec2_ami_image_id_boot_tpm: "{{ result.image_id }}"
ec2_ami_snapshot_boot_tpm: "{{ result.block_device_mapping[ec2_ami_root_disk].snapshot_id }}"

- name: gather facts about the image created
ec2_ami_info:
image_ids: '{{ ec2_ami_image_id_boot_tpm }}'
register: ami_facts_result_boot_tpm
ignore_errors: true
vars:
ansible_python_interpreter: "{{ botocore_virtualenv_interpreter }}"

- name: assert that new ami has been created with desired options
assert:
that:
- "result.changed"
- "result.image_id.startswith('ami-')"
- ami_facts_result_boot_tpm.images[0].image_id | length != 0
- ami_facts_result_boot_tpm.images[0].boot_mode == 'uefi'
- ami_facts_result_boot_tpm.images[0].tpm_support == 'v2.0'

# ============================================================

Expand All @@ -641,6 +708,13 @@
debug:
msg: "***** TESTING COMPLETE. COMMENCE TEARDOWN *****"

- name: delete ami
ec2_ami:
state: absent
image_id: "{{ ec2_ami_image_id_boot_tpm }}"
wait: yes
ignore_errors: yes

- name: delete ami
ec2_ami:
state: absent
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/plugins/modules/test_ec2_ami.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# This file is part of Ansible
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from unittest.mock import MagicMock, Mock, patch, call

import pytest

from ansible_collections.amazon.aws.plugins.modules import ec2_ami

module_name = "ansible_collections.amazon.aws.plugins.modules.ec2_ami"


@patch(module_name + ".get_image_by_id")
def test_create_image_uefi_data(m_get_image_by_id):
module = MagicMock()
connection = MagicMock()

m_get_image_by_id.return_value = {
"ImageId": "ami-0c7a795306730b288",
"BootMode": "uefi",
"TpmSupport": "v2.0",
}

module.params = {
"name": "my-image",
"boot_mode": "uefi",
"tpm_support": "v2.0",
"uefi_data": "QU1aTlVFRkk9xcN0AAAAAHj5a7fZ9+3aT2gcVRgA8Ek3NipiPST0pCiCIlTJtj20FzENCcQa",
}

ec2_ami.create_image(module, connection)
assert connection.register_image.call_count == 1
connection.register_image.assert_has_calls(
[
call(
aws_retry=True,
Description=None,
Name="my-image",
BootMode="uefi",
TpmSupport="v2.0",
UefiData="QU1aTlVFRkk9xcN0AAAAAHj5a7fZ9+3aT2gcVRgA8Ek3NipiPST0pCiCIlTJtj20FzENCcQa"
)
]
)

0 comments on commit 9e07cec

Please sign in to comment.