diff --git a/terraform/data_source_state.go b/terraform/data_source_state.go index 730158550..9cb39d0ea 100644 --- a/terraform/data_source_state.go +++ b/terraform/data_source_state.go @@ -37,6 +37,11 @@ func dataSourceRemoteState() *schema.Resource { Optional: true, }, + "defaults": { + Type: schema.TypeMap, + Optional: true, + }, + "environment": { Type: schema.TypeString, Optional: true, @@ -88,19 +93,22 @@ func dataSourceRemoteStateRead(d *schema.ResourceData, meta interface{}) error { if err := state.RefreshState(); err != nil { return err } - d.SetId(time.Now().UTC().String()) outputMap := make(map[string]interface{}) + defaults := d.Get("defaults").(map[string]interface{}) + for key, val := range defaults { + outputMap[key] = val + } + remoteState := state.State() if remoteState.Empty() { log.Println("[DEBUG] empty remote state") - return nil - } - - for key, val := range remoteState.RootModule().Outputs { - outputMap[key] = val.Value + } else { + for key, val := range remoteState.RootModule().Outputs { + outputMap[key] = val.Value + } } mappedOutputs := remoteStateFlatten(outputMap) @@ -108,5 +116,6 @@ func dataSourceRemoteStateRead(d *schema.ResourceData, meta interface{}) error { for key, val := range mappedOutputs { d.UnsafeSetFieldRaw(key, val) } + return nil } diff --git a/terraform/data_source_state_test.go b/terraform/data_source_state_test.go index 9a58b154f..bfabd27b1 100644 --- a/terraform/data_source_state_test.go +++ b/terraform/data_source_state_test.go @@ -63,6 +63,38 @@ func TestState_complexOutputs(t *testing.T) { }) } +func TestEmptyState_defaults(t *testing.T) { + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEmptyState_defaults, + Check: resource.ComposeTestCheckFunc( + testAccCheckStateValue( + "data.terraform_remote_state.foo", "foo", "bar"), + ), + }, + }, + }) +} + +func TestState_defaults(t *testing.T) { + resource.UnitTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEmptyState_defaults, + Check: resource.ComposeTestCheckFunc( + testAccCheckStateValue( + "data.terraform_remote_state.foo", "foo", "bar"), + ), + }, + }, + }) +} + func testAccCheckStateValue(id, name, value string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[id] @@ -109,3 +141,29 @@ resource "terraform_remote_state" "foo" { path = "./test-fixtures/complex_outputs.tfstate" } }` + +const testAccEmptyState_defaults = ` +data "terraform_remote_state" "foo" { + backend = "local" + + config { + path = "./test-fixtures/empty.tfstate" + } + + defaults { + foo = "bar" + } +}` + +const testAccState_defaults = ` +data "terraform_remote_state" "foo" { + backend = "local" + + config { + path = "./test-fixtures/basic.tfstate" + } + + defaults { + foo = "not bar" + } +}` diff --git a/website/docs/d/remote_state.html.md b/website/docs/d/remote_state.html.md index cec5d919b..138570922 100644 --- a/website/docs/d/remote_state.html.md +++ b/website/docs/d/remote_state.html.md @@ -33,6 +33,7 @@ The following arguments are supported: * `backend` - (Required) The remote backend to use. * `environment` - (Optional) The Terraform environment to use. * `config` - (Optional) The configuration of the remote backend. +* `defaults` - (Optional) default value for outputs in case state file is empty or it does not have the output. * Remote state config docs can be found [here](/docs/backends/types/terraform-enterprise.html) ## Attributes Reference