Terraform-provider-aws: Resource aws_ami_copy should allow for skip_destroy = true

Created on 13 Jun 2017  路  7Comments  路  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @dhoer as hashicorp/terraform#14736. It was migrated here as part of the provider split. The original body of the issue is below._


I want to keep the previous AMI created by aws_ami_copy, but it does a destroy first. It would be nice to add skip_destroy attribute that would allow for skipping the removal of the previous AMI created.

enhancement servicec2

Most helpful comment

I noticed this recently because I have an aws_ami_copy resource with most_recent = true that takes unencrypted Ubuntu AMIs and creates encrypted copies we use locally. Then we have a bunch of launch_configuration resources that find the latest encrypted AMI and use it.

When a new Ubuntu AMI is released, aws_ami_copy creates a new AMI copy and removes the old AMI copy, leaving the existing launch configurations on AWS referring to the old, deleted AMI. Further ASG activity that needs to launch new instances fails because the AMI doesn't exist.

I'd be happy to write a PR that implements this.

Is it as simple as adding a parameter to aws_ami_copy that prevents resourceAwsAmiCopy() from setting the Delete member of the schema resource (at https://github.com/terraform-providers/terraform-provider-aws/blob/177a198/aws/resource_aws_ami_copy.go#L57)? Then, the Terraform state gets updated for the new AMI, and the previous AMI simply dangles, unreferenced by any TF state?

All 7 comments

I noticed this recently because I have an aws_ami_copy resource with most_recent = true that takes unencrypted Ubuntu AMIs and creates encrypted copies we use locally. Then we have a bunch of launch_configuration resources that find the latest encrypted AMI and use it.

When a new Ubuntu AMI is released, aws_ami_copy creates a new AMI copy and removes the old AMI copy, leaving the existing launch configurations on AWS referring to the old, deleted AMI. Further ASG activity that needs to launch new instances fails because the AMI doesn't exist.

I'd be happy to write a PR that implements this.

Is it as simple as adding a parameter to aws_ami_copy that prevents resourceAwsAmiCopy() from setting the Delete member of the schema resource (at https://github.com/terraform-providers/terraform-provider-aws/blob/177a198/aws/resource_aws_ami_copy.go#L57)? Then, the Terraform state gets updated for the new AMI, and the previous AMI simply dangles, unreferenced by any TF state?

I'd love some quick feedback on the Terraform internals I mentioned above.

I'm happy to spend time on a PR, but I'm fairly new to Terraform internals, and some feedback would be encouraging. Thanks!

This is critical for ASG's that reference the old AMI. If you deregister the AMI, the ASG fails to launch any more instances.

@here Is there any update on this referenced above this is very annoying when it comes to using the aws_ami_copy in an ASG. The only work around I have come up with is having a lambda handle the ami copy and remove it from the TF lifecycle. Would welcome any other ways of getting around not deregistered the old AMI on build.

@sionsmith I ended up using aws-cli to create a CI AMI pipeline.

Example:

# Create selenium hub ami from instance
# use aws-cli until terraform issue #14841 is resolved
INSTANCE_HUB=$(aws ec2 describe-instances --region us-east-1 --filters Name=tag:Name,Values=selenium-ami-hub-win Name=instance-state-name,Values=running --query Reservations[0].Instances[*].InstanceId --output text)
AMI_HUB=$(aws ec2 create-image --region us-east-1 --instance-id ${INSTANCE_HUB} --name ${AMI_HUB_NAME} --description "Selenium Hub AMI" --output text)
aws ec2 create-tags --region us-east-1 --resources ${AMI_HUB} --tags Key=Name,Value=${AMI_HUB_NAME} Key=environment,Value=windows-selenium-hub

# Create selenium node ami from instance
# use aws-cli until terraform issue #14841 is resolved
INSTANCE_NODE=$(aws ec2 describe-instances --region us-east-1 --filters Name=tag:Name,Values=main-selenium-ami-node-win Name=instance-state-name,Values=running --query Reservations[0].Instances[*].InstanceId --output text)
AMI_NODE=$(aws ec2 create-image --region us-east-1 --instance-id ${INSTANCE_NODE} --name ${AMI_NODE_NAME} --description "Selenium Node AMI" --output text)
aws ec2 create-tags --region us-east-1 --resources ${AMI_NODE} --tags Key=Name,Value=${AMI_NODE_NAME} Key=environment,Value=windows-selenium-node

for i in {1..4}; do aws ec2 wait image-available --region us-east-1 --image-ids ${AMI_HUB} && break || true; done
for i in {1..4}; do aws ec2 wait image-available --region us-east-1 --image-ids ${AMI_NODE} && break || true; done

Thanks @dhoer So I ended up spending a lot long than expected on solving this.

  • Used CodeBuild to build AMI with a templated buildspec.yml which kicks of a Packer build and then send an event via aws cli to kick off a Lambda.
  • Lambda reads in ami-id from the event and copies AMI to specified region with the parametrised kms key.
  • I then use a standard datasource to read in newly created ami based on amended tags on the encrypted ami.

@here You are all welcome to the code which can be found here:
https://github.com/osodevops/aws-terraform-module-codebuild-packer

changes that I added to the module can be found here:
https://github.com/osodevops/aws-terraform-module-codebuild-packer/pull/1

Any questions let me know.

My use case was only to create encrypted AMIs to use with launch configs. Looks like I completely missed the encrypted flag on ebs_block_devices, which lets you enable encryption on root volumes without rebuilding/copying the AMI.

I'm not going to pursue this change further, but my very simple (and untested) code is at https://github.com/jwm/terraform-provider-aws/commits/jwm/aws_ami_copy_skip_destroy -- I'd be happy if anyone else picks it up and runs with it.

Was this page helpful?
0 / 5 - 0 ratings