Reputation: 111
I'm trying to implement some sort of mechanism where someone can fill in a variable which defines if it's going to deploy an Amazon Linux machine or a self-created packer machine. But for some reason it's not picking up the AWS AMI while it does find my own. Here's the code:
Main.tf of the module:
data "aws_ami" "latest" {
most_recent = true
owners = [var.owner]
filter {
name = "name"
values = [lookup(var.default_ami, var.ami)]
}
}
resource "aws_instance" "test-ec2deployment" {
ami = data.aws_ami.latest.id
variables.tf:
variable "default_ami" {
type = map
description = "Choose windows 2016 or 2019"
default = {
"2016" = "WIN2016-CUSTOM*"
"2019" = "WIN2019-CUSTOM*"
"linux" = "ami-0fb02dcdd38048fb9"
}
}
#Above are the options, here you need to make a decision.
variable "ami" {
description = "You can either choose the 2019 or the 2016 image or the linux image."
default = "2019"
}
And finally the main.tf which calls on the module:
module "aws_instance" {
shared_credentials_file = ""
source = ""
env_name = ""
volume_size = "60"
ami = "linux"
}
Like i said, it does find the correct image when i'm entering either 2019 or 2016. The error message is as follows:
module.aws_instance.data.aws_ami.latest: Refreshing state...
Error: Your query returned no results. Please change your search criteria and try again.
Any idea's?
Thanks for the help!
PS: I've emptied some fields on purpose.
Upvotes: 7
Views: 23568
Reputation: 9427
If you are searching by name, you may want to use wildcards. For example, there is an ecs-optimized ami named amzn2-ami-ecs-hvm-2.0.20220318-x86_64-ebs
. However, terraform couldn't find it. When I used wildcards, it worked: amzn2-ami-ecs-hvm-2.0.202*-x86_64-ebs
The actual code looks as so:
data "aws_ami" "ecs_optimized_ami" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-ecs-hvm-2.0.202*-x86_64-ebs"]
}
}
Upvotes: 2
Reputation: 81
Marcin's answer is spot on. AMI name and AMI id are two different things, you cannot use AMI id to search AMI based on its name. For using AMI id, you need to use "image-id" filter. To get a complete list of filters that we can use for searching AMI, check this.
Now, coming to your problem. You can use "name" and "image-id" filter together to get the required AMI. If you don't have value for any of them use "*". I solved it in the following way -
variable "ami" {
description = "You can either choose the 2019 or the 2016 image or the linux image."
default = "2019"
}
variable "default_ami" {
type = map(any)
default = {
"linux" = {
name = "*"
ami_id = "ami-0fb02dcdd38048fb9"
},
"2016" = {
name = "WIN2016-CUSTOM*"
ami_id = "*"
},
"2019" = {
name = "WIN2019-CUSTOM*"
ami_id = "*"
}
}
}
data "aws_ami" "latest" {
most_recent = true
owners = [var.owner]
filter {
name = "name"
values = ["${var.default_ami[var.ami]["name"]}"]
}
filter {
name = "image-id"
values = ["${var.default_ami[var.ami]["ami_id"]}"]
}
}
resource "aws_instance" "test-ec2deployment" {
ami = data.aws_ami.latest.id
instance_type = var.instance_type
}
Upvotes: 4
Reputation: 238309
AMI name and AMI id are two different things. You are using AMI id (ami-0fb02dcdd38048fb9) to search AMI based on its name. This will not work obviously. You have to replace ami-0fb02dcdd38048fb9
with AMI name.
You haven't specified how you named your linux
AMI, maybe Linux2019-CUSTOM*
? Whatever the name you've used, you have to use that, not AMI id.
Upvotes: 1