user3847894
user3847894

Reputation: 1054

Interpolate data source

I am trying to create some generic Terraform code which supports different MySQL version AMIs. AMIs of MySQL are not in my AWS account. They are in a different AWS account and shared with my account. I am using a data source to get the latest MySQL AMIs from different account. Now I want to have some thing like this

terraform apply -var somevar=mysql5.6 (This should use mysql5.6 AMI for creating resources)
terraform apply -var somevar=mysql5.5 (This should use mysql5.5 AMI for creating resources)

But the problem is that I can't variablize/interpolate data source mentioned in resource section. Is there any other way to get what I am looking for?

This is the excerpt of what I tried till now

data "aws_ami" "mysql56" {
  owners = ["xxxxxxxxxxxx"]

  most_recent = true

  filter {
    name   = "image-id"
    values = ["${var.os_to_ami["mysql56"]}"]
  }
}

data "aws_ami" "mysql55" {
  owners = ["xxxxxxxxxxxx"]

  most_recent = true

  filter {
    name   = "image-id"
    values = ["${var.os_to_ami["mysql55"]}"]
  }
}
variable "os_to_ami" {
  type = "map"
  description = "OS to AMI mapping"
  default = {
        "mysql56" = "ami-xxxxxxxxxxxxxxxxx"
        "mysql57" = "ami-yyyyyyyyyyyyyyyyy"
  }
}

resource "aws_instance" "web" {
ami            = "${data.aws_ami.mysql56}"
...
}

I am using Terraform v0.11.0.

Upvotes: 0

Views: 50

Answers (1)

ydaetskcoR
ydaetskcoR

Reputation: 56877

Your data sources aren't doing anything useful because you're passing the AMI ID into them which defeats the point of them. Instead you should be using the aws_ami data source to fetch the AMI ID based on some criteria such as the owner and the name. This would then let you more simply look these up based on a variable.

Assuming the AMIs are being shared by account 123456789012 and have the names mysql/mysql-5.5/20200818T212500Z and mysql/mysql-5.6/20200818T212500Z then you'd do something like the following:

variable "mysql_version" {}

data "aws_ami" "mysql" {
  most_recent = true

  filter {
    name   = "name"
    values = ["mysql/mysql-${var.mysql_version}/*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["123456789012"]
}

resource "aws_instance" "mysql" {
  ami           = data.aws_ami.mysql.id
  instance_type = "t3.micro"
}

With the above you have a required mysql_version variable that must be provided. This is then interpolated into the AMI name to search for and will return the latest one matching those criteria so if a new AMI was to be published by the 123456789012 account owner for the same MySQL version with a different timestamp then it would want to recreate your instance with that new AMI.

Upvotes: 1

Related Questions