Terraform: Feature Request: Write outputs to disk automatically when terraform apply is run

Created on 7 Apr 2017  路  5Comments  路  Source: hashicorp/terraform

Hi there,

Please direct me to the appropriate place if this is already available somehow, but I've looked around and haven't found anything.

The intent for this request is to make the outputs more usable by others. For example, I want to use the vpc id, which is a terraform output, as an input variable in my Ansible playbook.

Before v0.9, I was just parsing the .terraform/terraform.tfstate file to get the ouputs, but it looks like since v0.9, the state file no longer contains the state information if I'm using remote state. My current workaround is to run terraform output -json > outputs.json every time I run terraform apply and then make Ansible read from this file.

It will be great if terraform apply will automatically do this, and we can configure the following settings:

  1. Whether we want to write the output to file at all
  2. The path to write to
  3. The format of the output
cli enhancement

Most helpful comment

Thanks for sharing that, @nbering. Either using terraform state pull or terraform output -json and then parsing the result is a good workaround for now.

An alternative, which doesn't actually use outputs at all but may serve a similar purpose, is to use the local_file resource to write out a data file to disk, separately from the outputs.

resource "local_file" "vpc_id" {
  content  = "${aws_vpc.example.id}"
  filename = "vpc_id.txt"
}

This approach allows you to customize the content of this file for this specific use-case if needed, separately from what is returned in outputs. If there are multiple values to return, the jsonencode function may be useful to encode them all together, although indeed at the moment this has some limitations.

Making Terraform automatically do something like terraform output -json > outputs.json as a side-effect of Terraform apply is an interesting idea. At the moment we're hesitant to add things like this because of the additional complexity it creates for automated testing, backward-compatibility, etc. However, eventually Terraform core development will stabilize and we'll be in a better position to invest in helpful shortcuts like this. In the mean time, I'd encourage the use of any of the three approaches discussed here to address this in the mean time.

All 5 comments

I would advocate for this as well, primarily because tf output foo can be _really_, _really_ slow when you have dozens or a few hundred resources.

For my ansible dynamic inventory script, I shell out to terraform state pull and then parse the state from stdout. There's a few advantages to this over reading from disk:

  • It will always be up-to-date even if someone ran terraform on another machine.
  • My script requires no knowledge of terraform backends - terraform is handling that part.
  • It's better than terraform output because it pulls the whole state file once, no need to re-read from the backend multiple times if you have submodules to read outputs from.
  • Not storing the state on disk on my computer limits exposure risk for secret values like access keys in the terraform state.

It has this disadvantage:

  • The initial load can still be a little slow while terraform fetches from remote state.

Thanks for sharing that, @nbering. Either using terraform state pull or terraform output -json and then parsing the result is a good workaround for now.

An alternative, which doesn't actually use outputs at all but may serve a similar purpose, is to use the local_file resource to write out a data file to disk, separately from the outputs.

resource "local_file" "vpc_id" {
  content  = "${aws_vpc.example.id}"
  filename = "vpc_id.txt"
}

This approach allows you to customize the content of this file for this specific use-case if needed, separately from what is returned in outputs. If there are multiple values to return, the jsonencode function may be useful to encode them all together, although indeed at the moment this has some limitations.

Making Terraform automatically do something like terraform output -json > outputs.json as a side-effect of Terraform apply is an interesting idea. At the moment we're hesitant to add things like this because of the additional complexity it creates for automated testing, backward-compatibility, etc. However, eventually Terraform core development will stabilize and we'll be in a better position to invest in helpful shortcuts like this. In the mean time, I'd encourage the use of any of the three approaches discussed here to address this in the mean time.

I am trying to achieve this with both but state pull never seems to save file, using azure devops ubuntu agent

I guess the current way is to for ex.:

tf resource "local_file" "ips" { filename = "${path.module}/ips.txt" content = join("\n", "${digitalocean_droplet.etcd.*.ipv4_address}") }

Was this page helpful?
0 / 5 - 0 ratings