{"action":"created","issue":{"url":"https://api.github.com/repos/hashicorp/terraform/issues/3164","labels_url":"https://api.github.com/repos/hashicorp/terraform/issues/3164/labels{/name}","comments_url":"https://api.github.com/repos/hashicorp/terraform/issues/3164/comments","events_url":"https://api.github.com/repos/hashicorp/terraform/issues/3164/events","html_url":"https://github.com/hashicorp/terraform/pull/3164","id":104738818,"number":3164,"title":"terraform_synthetic_state resource","user":{"login":"apparentlymart","id":20180,"avatar_url":"https://avatars.githubusercontent.com/u/20180?v=3","gravatar_id":"","url":"https://api.github.com/users/apparentlymart","html_url":"https://github.com/apparentlymart","followers_url":"https://api.github.com/users/apparentlymart/followers","following_url":"https://api.github.com/users/apparentlymart/following{/other_user}","gists_url":"https://api.github.com/users/apparentlymart/gists{/gist_id}","starred_url":"https://api.github.com/users/apparentlymart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apparentlymart/subscriptions","organizations_url":"https://api.github.com/users/apparentlymart/orgs","repos_url":"https://api.github.com/users/apparentlymart/repos","events_url":"https://api.github.com/users/apparentlymart/events{/privacy}","received_events_url":"https://api.github.com/users/apparentlymart/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/hashicorp/terraform/labels/enhancement","name":"enhancement","color":"d4c5f9"},{"url":"https://api.github.com/repos/hashicorp/terraform/labels/proposal","name":"proposal","color":"fbca04"},{"url":"https://api.github.com/repos/hashicorp/terraform/labels/thinking","name":"thinking","color":"fad8c7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-09-03T16:55:53Z","updated_at":"2015-11-30T23:52:04Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/hashicorp/terraform/pulls/3164","html_url":"https://github.com/hashicorp/terraform/pull/3164","diff_url":"https://github.com/hashicorp/terraform/pull/3164.diff","patch_url":"https://github.com/hashicorp/terraform/pull/3164.patch"},"body":"The normal way to share a state for consumption by downstream ``terraform_remote_state`` is to just point consumers at the same configuration used to persist the configuration state itself.\r\n\r\nThis is fine most of the time, but sometimes it's desirable to present downstream consumers with a different level of abstraction than the physical configuration represents. For example, one might create AWS infrastructure on a per-region basis but expose it to downstream configurations on a per-availability-zone basis.\r\n\r\nThis resource thus allows a Terraform configuration to produce additional \"synthetic\" remote states, containing only outputs, that are intended only for downstream consumption and are not used to actually manage any resources. They contain only outputs, and no resource states.\r\n\r\nThis is a real use-case I have: we maintain environments as a collection of \"physical\" configurations, which create resources on a per-AWS-region basis, and then we currently maintain a collection of \"logical\" configurations that do nothing except read the physical remote states and project their data into an availability-zone-oriented basis that our downstream app infrastructure deployments expect.\r\n\r\nI'd like to simplify by eliminating that extra level of logical configuration, and just have the physical configurations write out a set of synthetic states for our downstream configs to consume:\r\n\r\n```js\r\nresource \"terraform_synthetic_state\" \"usw1a\" {\r\n    backend = \"consul\"\r\n    config = { ... }\r\n    outputs = {\r\n        availability_zone = \"us-west-1a\"\r\n        region = \"us-west-1\"\r\n        vpc_id = \"${aws_vpc.main.id}\"\r\n        subnet_id = \"${aws_subnet.usw1a.id}\"\r\n        // ...\r\n    }\r\n}\r\n\r\nresource \"terraform_synthetic_state\" \"usw1b\" {\r\n    backend = \"consul\"\r\n    config = { ... }\r\n    outputs = {\r\n        availability_zone = \"us-west-1b\"\r\n        region = \"us-west-1\"\r\n        vpc_id = \"${aws_vpc.main.id}\"\r\n        subnet_id = \"${aws_subnet.usw1b.id}\"\r\n        // ...\r\n    }\r\n}\r\n```\r\n\r\nWhile I'm sure we could share such configuration data a different way if forced to, I think it's convenient for downstream consumers to not have to think about two different mechanisms for consuming upstream data depending on whether it's a \"real\" Terraform state or just some derived outputs.\r\n\r\nSo far I just wrote the main implementation to get some feedback. If this seems like something that would be accepted into Terraform then I'll follow up with some tests and documentation.\r\n"},"comment":{"url":"https://api.github.com/repos/hashicorp/terraform/issues/comments/160801662","html_url":"https://github.com/hashicorp/terraform/pull/3164#issuecomment-160801662","issue_url":"https://api.github.com/repos/hashicorp/terraform/issues/3164","id":160801662,"user":{"login":"phinze","id":37534,"avatar_url":"https://avatars.githubusercontent.com/u/37534?v=3","gravatar_id":"","url":"https://api.github.com/users/phinze","html_url":"https://github.com/phinze","followers_url":"https://api.github.com/users/phinze/followers","following_url":"https://api.github.com/users/phinze/following{/other_user}","gists_url":"https://api.github.com/users/phinze/gists{/gist_id}","starred_url":"https://api.github.com/users/phinze/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phinze/subscriptions","organizations_url":"https://api.github.com/users/phinze/orgs","repos_url":"https://api.github.com/users/phinze/repos","events_url":"https://api.github.com/users/phinze/events{/privacy}","received_events_url":"https://api.github.com/users/phinze/received_events","type":"User","site_admin":false},"created_at":"2015-11-30T23:52:04Z","updated_at":"2015-11-30T23:52:04Z","body":"Hey @apparentlymart - just had a chance to review this.\r\n\r\nThis is super interesting - it turns the remote state from being a \"pull\" of all outputs for a given live config to a \"push\" / \"publish\" model.\r\n\r\nBefore we consider pulling this implementation in as-is I'd like to take a step back and spec out the abstract need this fulfills to help us decide if a `terraform_synthetic_state` resource is the proper solution to pull in. Let me do some thinking on this and I'll get back to you."}}