简体   繁体   中英

Reading terraform variable from file

In terraform, long keys can be specified as follows:

resource "aws_iam_role_policy" "foo-policy" {
    role = "${aws_iam_role.foo-role.name}"
    name = "foo-policy"

    policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams"
            ],
            "Resource": [
                "arn:aws:logs:*:*:*"
            ]
        }
    ]
}
EOF
}

This is a common pattern for IAM policy documents. The approach is documented here and is the example given in the AWS IAM role policy page on terraform . Is there a way to instead read the document from an external file?

This has numerous advantages:

  • you can use tools to generate the policy
  • you can use linting tools to validate the policy JSON. Also editor syntax highlighting will work, showing JSON mistakes like trailing commas.
  • you can use more advanced tools to validate the policy document syntax

You can use terraform's template_file data source for this. Simply write your policy out to a file in a path that your terraform scripts can access, and then create a template_file data source that references it. For example:

data "template_file" "policy" {
  template = "${file("somepath/my-policy.json")}"
}

And then, in foo-policy, you would render it like so:

policy = "${data.template_file.policy.rendered}"

An additional benefit of template_file is that you can interpolate variables within the referenced file. For example, you could have variables like ${IAMUser} or ${AWSAccountNumber} in your policy and pass it in via the template_file vars option, which would allow you to reuse the policy file.

Further Reading

In Terraform 0.12 and later there are special functions to read out files:

  • file reads the contents of a file at the given path and returns them as a string.
  • templatefile function offers a built-in mechanism for rendering a template from a file.

Use that functions instead of template_file data source.

    resource "aws_instance" "ami-example" {
      ami           = "ami-0c55b159cbfafe1f0"
      instance_type = "t2.micro"
      vpc_security_group_ids = [aws_security_group.instance.id]
      user_data     = <<-EOF
              #!/bin/bash
              echo "${file("index.html")}" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF
      tags = {
        "source" = "terraform"
        "Name"   = "tf-ami-example"
      }
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM