Skip to content

Commit

Permalink
aws_ami: Support setting the imds_support attribute at registration t…
Browse files Browse the repository at this point in the history
…ime (closes hashicorp#27083)
  • Loading branch information
christophetd committed Oct 4, 2022
1 parent 8d54b62 commit 67d98b6
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 1 deletion.
11 changes: 11 additions & 0 deletions internal/service/ec2/ec2_ami.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@ func ResourceAMI() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"imds_support": {
Type: schema.TypeString,
Optional: true,
ForceNew: true, // this attribute can only be set at registration time
ValidateFunc: validation.StringInSlice([]string{"v2.0"}, false),
},
"kernel_id": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -342,6 +348,10 @@ func resourceAMICreate(d *schema.ResourceData, meta interface{}) error {
input.BlockDeviceMappings = append(input.BlockDeviceMappings, expandBlockDeviceMappingsForAMIEphemeralBlockDevice(v.(*schema.Set).List())...)
}

if v := d.Get("imds_support").(string); v != "" {
input.ImdsSupport = aws.String(v)
}

output, err := conn.RegisterImage(input)

if err != nil {
Expand Down Expand Up @@ -419,6 +429,7 @@ func resourceAMIRead(d *schema.ResourceData, meta interface{}) error {
d.Set("image_location", image.ImageLocation)
d.Set("image_owner_alias", image.ImageOwnerAlias)
d.Set("image_type", image.ImageType)
d.Set("imds_support", image.ImdsSupport)
d.Set("kernel_id", image.KernelId)
d.Set("name", image.Name)
d.Set("owner_id", image.OwnerId)
Expand Down
6 changes: 6 additions & 0 deletions internal/service/ec2/ec2_ami_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ func DataSourceAMI() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"imds_support": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"v2.0"}, false),
},
"include_deprecated": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -302,6 +307,7 @@ func amiDescriptionAttributes(d *schema.ResourceData, image *ec2.Image, meta int
d.Set("image_location", image.ImageLocation)
d.Set("image_owner_alias", image.ImageOwnerAlias)
d.Set("image_type", image.ImageType)
d.Set("imds_support", image.ImdsSupport)
d.Set("kernel_id", image.KernelId)
d.Set("name", image.Name)
d.Set("owner_id", image.OwnerId)
Expand Down
1 change: 1 addition & 0 deletions internal/service/ec2/ec2_ami_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestAccEC2AMIDataSource_natInstance(t *testing.T) {
resource.TestMatchResourceAttr(resourceName, "image_location", regexp.MustCompile("^amazon/")),
resource.TestCheckResourceAttr(resourceName, "image_owner_alias", "amazon"),
resource.TestCheckResourceAttr(resourceName, "image_type", "machine"),
resource.TestCheckResourceAttr(resourceName, "imds_support", ""),
resource.TestCheckResourceAttr(resourceName, "most_recent", "true"),
resource.TestMatchResourceAttr(resourceName, "name", regexp.MustCompile("^amzn-ami-vpc-nat")),
acctest.MatchResourceAttrAccountID(resourceName, "owner_id"),
Expand Down
50 changes: 50 additions & 0 deletions internal/service/ec2/ec2_ami_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestAccEC2AMI_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "ephemeral_block_device.#", "0"),
resource.TestCheckResourceAttr(resourceName, "hypervisor", "xen"),
resource.TestCheckResourceAttr(resourceName, "image_type", "machine"),
resource.TestCheckResourceAttr(resourceName, "imds_support", ""),
resource.TestCheckResourceAttr(resourceName, "kernel_id", ""),
resource.TestCheckResourceAttr(resourceName, "name", rName),
acctest.CheckResourceAttrAccountID(resourceName, "owner_id"),
Expand Down Expand Up @@ -549,6 +550,36 @@ func TestAccEC2AMI_tpmSupport(t *testing.T) {
})
}

func TestAccEC2AMI_imdsSupport(t *testing.T) {
var ami ec2.Image
resourceName := "aws_ami.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckAMIDestroy,
Steps: []resource.TestStep{
{
Config: testAccAMIConfig_imdsSupport(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAMIExists(resourceName, &ami),
resource.TestCheckResourceAttr(resourceName, "imds_support", "v2.0"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"manage_ebs_snapshots",
},
},
},
})
}

func testAccCheckAMIDestroy(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn

Expand Down Expand Up @@ -848,3 +879,22 @@ resource "aws_ami" "test" {
}
`, rName))
}

func testAccAMIConfig_imdsSupport(rName string) string {
return acctest.ConfigCompose(
testAccAMIConfig_base(rName),
fmt.Sprintf(`
resource "aws_ami" "test" {
name = %[1]q
root_device_name = "/dev/xvda"
virtualization_type = "hvm"
boot_mode = "uefi"
imds_support = "v2.0"
ebs_block_device {
device_name = "/dev/xvda"
snapshot_id = aws_ebs_snapshot.test.id
}
}
`, rName))
}
1 change: 1 addition & 0 deletions website/docs/d/ami.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ interpolation.
* `image_owner_alias` - AWS account alias (for example, `amazon`, `self`) or
the AWS account ID of the AMI owner.
* `image_type` - Type of image.
* `imds_support` - Instance Metadata Service (IMDS) support mode for the image. Set to `v2.0` if instances ran from this image enforce IMDSv2.
* `kernel_id` - Kernel associated with the image, if any. Only applicable
for machine images.
* `name` - Name of the AMI that was provided during image creation.
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/ami.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ resource "aws_ami" "example" {
name = "terraform-example"
virtualization_type = "hvm"
root_device_name = "/dev/xvda"
imds_support = "v2.0" # Enforce usage of IMDSv2. You can safely remove this line if your application explicitly doesn't support it.
ebs_block_device {
device_name = "/dev/xvda"
snapshot_id = "snap-xxxxxxxx"
Expand Down Expand Up @@ -56,6 +56,7 @@ The following arguments are supported:
should be attached to created instances. The structure of this block is described below.
* `tags` - (Optional) Map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
* `tpm_support` - (Optional) If the image is configured for NitroTPM support, the value is `v2.0`. For more information, see [NitroTPM](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nitrotpm.html) in the Amazon Elastic Compute Cloud User Guide.
* `imds_support` - (Optional) If EC2 instances started from this image should require the use of the Instance Metadata Service V2 (IMDSv2), set this argument to `v2.0`. For more information, see [Configure instance metadata options for new instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-IMDS-new-instances.html#configure-IMDS-new-instances-ami-configuration).

When `virtualization_type` is "paravirtual" the following additional arguments apply:

Expand Down

0 comments on commit 67d98b6

Please sign in to comment.