hashicorp / packer

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.
http://www.packer.io
Other
15.03k stars 3.32k forks source link

Amazon EBS Builder Filter by Untagged / Ignore Filter #9446

Closed HeroCC closed 4 years ago

HeroCC commented 4 years ago

Before I get into the actual feature request, I'll describe my use case to see if there's a better way. I have a packerfile that by default selects an image though source_ami_filter. It is run as a parameterized build in Jenkins, where the default aws_source_ami_id is blank, leaving packer to pick it's own path. However, I'd like to allow users to be able to override this filter and pick their own ami, regardless of the value of the tag. I tried setting aws_ami_tag_filter=*, but that still requires the AMI be tagged, it just doesn't care about the value.

Essentially, right now source_ami is a part of source_ami_filter, but I want source_ami to always override source_ami_filter, and ignore if there are conflicts. I couldn't find a glob to properly ignore the tag's value, so here I am.

Here is a small code sample:

"variables": {
    "aws_source_ami_id": "",
    "aws_ami_tag_filter": "Ready",
}
...
"source_ami_filter": {
  "filters": {
    "tag:TemplateStatus": "{{user `aws_ami_tag_filter`}}"
  },
 "owners": ["self"],
  "most_recent": true
},
"source_ami": "{{user `aws_source_ami_id`}}",

Now, on to what I think would be a good generic solution, but please correct me if I'm wrong.

Feature Description

I wasn't able to find a glob to select 'Unset' for a tag, so I'd like to find a way to filter for images that don't have a certain tag, within the filter value. Ideally, this would be able to be combined with other globs, so I could, for example, select an AMI with a tag that's either unset or set to a specific value.

Use Case(s)

See above :)

SwampDragons commented 4 years ago

Hi, thanks for reaching out!

I don't think we can easily support what you're asking for; our ami filter is a direct pass-through to the AWS api and I'm hesitant to add extra packer-specific functionality on top of what you're getting via that api. I think that would make it harder for users to know what can and can't be done via filters.

That said, there is a workaround I can think of, though it'll be a bit of extra work for you to implement.

If you switch from using JSON templates to HCL, you can use HCL's improved variable handling and conditional logic to remove the tag filters when you've set the source_ami variable. Here's a gist with an aws + HCL2 example, that conditionally changes the filters based on the value of a source_ami variable:

https://gist.github.com/SwampDragons/76e3067ef4fca6d26b1d1ae07fd3ad84

HCL support is still in beta and changing a bit as we figure things out, so this isn't necessarily a set-it-and-forget-it solution. If you decide to go this route please let us know if you hit any snags.

If that feels like too much work for you, you may just want to use jq or a similar tool in a wrapping script to strip the "tag" line from the filters when source_ami is set.

An example of a jq command that will remove your tag from the filter in your aws config:

jq 'walk(if type == "object" then del(."tag:TemplateStatus") else . end)' base_aws.json > filterless_aws.json

HeroCC commented 4 years ago

That makes sense not wanting to add extra layers. Thank you for your suggestions otherwise! I will take a look at them. Enjoy your day!

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.