Terraform - Get a value from parameter store and pass to resource

17,712

You can use the aws_ssm_parameter data source to fetch the value of a parameter at runtime:

data "aws_ssm_parameter" "ami" {
  name = "/path/to/ami"
}

resource "aws_instance" "nginx" {
  ami           = data.aws_ssm_parameter.ami.value # pull value from parameter store
  instance_type = "t2.micro"

  provisioner "remote-exec" {
    inline = [
      "sudo yum install nginx -y",
      "sudo service nginx start"
    ]
  }
}

However, a better approach might be to use the aws_ami data source to filter for the AMI you want more directly instead of pushing the AMI ID to SSM parameter store and then looking it up later. You can filter on a number of criteria including name, account owner and tags. Here's the example from the aws_instance resource documentation that is looking for the latest Ubuntu 20.04 AMI:

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

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

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"

  tags = {
    Name = "HelloWorld"
  }
}
Share:
17,712
navig8tr
Author by

navig8tr

Updated on June 14, 2022

Comments

  • navig8tr
    navig8tr almost 2 years

    We store our latest approved AMIs in AWS parameter store. When creating new instances with Terraform I would like to programatically get this AMI ID. I have a command to pull the AMI ID but I'm not sure how to use it with Terraform.

    Here is the command I use to pull the AMI ID:

    $(aws ssm get-parameter --name /path/to/ami --query 'Parameter.Value' --output text)
    

    And here is my Terraform script:

    resource "aws_instance" "nginx" {
      ami           = "ami-c58c1dd3" # pull value from parameter store
      instance_type = "t2.micro"
      #key_name        = "${var.key_name}"
    
      provisioner "remote-exec" {
        inline = [
          "sudo yum install nginx -y",
          "sudo service nginx start"
        ]
      }
    }
    

    How can I use the command to pull the AMI ID in the Terraform script?

  • navig8tr
    navig8tr over 4 years
    We can't use your second option as our ami's go through an approval process by another team and are then posted in parameter store for us to use. First option works perfect though
  • ydaetskcoR
    ydaetskcoR over 4 years
    Your other team could apply a specific tag that you filter for. Might work, might not but thought it was worth suggesting as an idea anyway.
  • The Unknown Dev
    The Unknown Dev over 3 years
    Thanks for the answer! Is it necessary to use string interpolation here? Can't you do ami = data.aws_ssm_parameter.ami.value without quoting it?
  • ydaetskcoR
    ydaetskcoR over 3 years
    Yes but the question used the HCL1 syntax so the answer also used it. HCL2 syntax allows both but will warn on the unnecessary interpolation there.
  • ydaetskcoR
    ydaetskcoR almost 3 years
    Updated the answer to HCL2 syntax as 0.12 came out long enough ago that I'm slowly updating answers to HCL2 syntax even where the original question was 0.11 unless the question specifically wanted a HCL1/0.11 answer.