Merge pull request #30138 from hashicorp/alisdair/json-module-call-providers-mapping
jsonconfig: Improve provider configuration output
This commit is contained in:
commit
d8018270a7
|
@ -27,10 +27,12 @@ type config struct {
|
||||||
// module boundaries.
|
// module boundaries.
|
||||||
type providerConfig struct {
|
type providerConfig struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
FullName string `json:"full_name,omitempty"`
|
||||||
Alias string `json:"alias,omitempty"`
|
Alias string `json:"alias,omitempty"`
|
||||||
VersionConstraint string `json:"version_constraint,omitempty"`
|
VersionConstraint string `json:"version_constraint,omitempty"`
|
||||||
ModuleAddress string `json:"module_address,omitempty"`
|
ModuleAddress string `json:"module_address,omitempty"`
|
||||||
Expressions map[string]interface{} `json:"expressions,omitempty"`
|
Expressions map[string]interface{} `json:"expressions,omitempty"`
|
||||||
|
parentKey string
|
||||||
}
|
}
|
||||||
|
|
||||||
type module struct {
|
type module struct {
|
||||||
|
@ -120,7 +122,6 @@ func Marshal(c *configs.Config, schemas *terraform.Schemas) ([]byte, error) {
|
||||||
|
|
||||||
pcs := make(map[string]providerConfig)
|
pcs := make(map[string]providerConfig)
|
||||||
marshalProviderConfigs(c, schemas, pcs)
|
marshalProviderConfigs(c, schemas, pcs)
|
||||||
output.ProviderConfigs = pcs
|
|
||||||
|
|
||||||
rootModule, err := marshalModule(c, schemas, "")
|
rootModule, err := marshalModule(c, schemas, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -128,6 +129,15 @@ func Marshal(c *configs.Config, schemas *terraform.Schemas) ([]byte, error) {
|
||||||
}
|
}
|
||||||
output.RootModule = rootModule
|
output.RootModule = rootModule
|
||||||
|
|
||||||
|
normalizeModuleProviderKeys(&rootModule, pcs)
|
||||||
|
|
||||||
|
for name, pc := range pcs {
|
||||||
|
if pc.parentKey != "" {
|
||||||
|
delete(pcs, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.ProviderConfigs = pcs
|
||||||
|
|
||||||
ret, err := json.Marshal(output)
|
ret, err := json.Marshal(output)
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
@ -154,6 +164,7 @@ func marshalProviderConfigs(
|
||||||
|
|
||||||
p := providerConfig{
|
p := providerConfig{
|
||||||
Name: pc.Name,
|
Name: pc.Name,
|
||||||
|
FullName: providerFqn.String(),
|
||||||
Alias: pc.Alias,
|
Alias: pc.Alias,
|
||||||
ModuleAddress: c.Path.String(),
|
ModuleAddress: c.Path.String(),
|
||||||
Expressions: marshalExpressions(pc.Config, schema),
|
Expressions: marshalExpressions(pc.Config, schema),
|
||||||
|
@ -176,6 +187,30 @@ func marshalProviderConfigs(
|
||||||
// Ensure that any required providers with no associated configuration
|
// Ensure that any required providers with no associated configuration
|
||||||
// block are included in the set.
|
// block are included in the set.
|
||||||
for k, pr := range c.Module.ProviderRequirements.RequiredProviders {
|
for k, pr := range c.Module.ProviderRequirements.RequiredProviders {
|
||||||
|
// If a provider has aliases defined, process those first.
|
||||||
|
for _, alias := range pr.Aliases {
|
||||||
|
// If there exists a value for this provider, we have nothing to add
|
||||||
|
// to it, so skip.
|
||||||
|
key := opaqueProviderKey(alias.StringCompact(), c.Path.String())
|
||||||
|
if _, exists := m[key]; exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Given no provider configuration block exists, the only fields we can
|
||||||
|
// fill here are the local name, FQN, module address, and version
|
||||||
|
// constraints.
|
||||||
|
p := providerConfig{
|
||||||
|
Name: pr.Name,
|
||||||
|
FullName: pr.Type.String(),
|
||||||
|
ModuleAddress: c.Path.String(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if vc, ok := reqs[pr.Type]; ok {
|
||||||
|
p.VersionConstraint = getproviders.VersionConstraintsString(vc)
|
||||||
|
}
|
||||||
|
|
||||||
|
m[key] = p
|
||||||
|
}
|
||||||
|
|
||||||
// If there exists a value for this provider, we have nothing to add
|
// If there exists a value for this provider, we have nothing to add
|
||||||
// to it, so skip.
|
// to it, so skip.
|
||||||
key := opaqueProviderKey(k, c.Path.String())
|
key := opaqueProviderKey(k, c.Path.String())
|
||||||
|
@ -188,6 +223,7 @@ func marshalProviderConfigs(
|
||||||
// constraints.
|
// constraints.
|
||||||
p := providerConfig{
|
p := providerConfig{
|
||||||
Name: pr.Name,
|
Name: pr.Name,
|
||||||
|
FullName: pr.Type.String(),
|
||||||
ModuleAddress: c.Path.String(),
|
ModuleAddress: c.Path.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +235,53 @@ func marshalProviderConfigs(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must also visit our child modules, recursively.
|
// Must also visit our child modules, recursively.
|
||||||
for _, cc := range c.Children {
|
for name, mc := range c.Module.ModuleCalls {
|
||||||
|
// Keys in c.Children are guaranteed to match those in c.Module.ModuleCalls
|
||||||
|
cc := c.Children[name]
|
||||||
|
|
||||||
|
// Add provider config map entries for passed provider configs,
|
||||||
|
// pointing at the passed configuration
|
||||||
|
for _, ppc := range mc.Providers {
|
||||||
|
// These provider names include aliases, if set
|
||||||
|
moduleProviderName := ppc.InChild.String()
|
||||||
|
parentProviderName := ppc.InParent.String()
|
||||||
|
|
||||||
|
// Look up the provider FQN from the module context, using the non-aliased local name
|
||||||
|
providerFqn := cc.ProviderForConfigAddr(addrs.LocalProviderConfig{LocalName: ppc.InChild.Name})
|
||||||
|
|
||||||
|
// The presence of passed provider configs means that we cannot have
|
||||||
|
// any configuration expressions or version constraints here
|
||||||
|
p := providerConfig{
|
||||||
|
Name: moduleProviderName,
|
||||||
|
FullName: providerFqn.String(),
|
||||||
|
ModuleAddress: cc.Path.String(),
|
||||||
|
}
|
||||||
|
|
||||||
|
key := opaqueProviderKey(moduleProviderName, cc.Path.String())
|
||||||
|
parentKey := opaqueProviderKey(parentProviderName, cc.Parent.Path.String())
|
||||||
|
|
||||||
|
// Traverse up the module call tree until we find the provider
|
||||||
|
// configuration which has no linked parent config. This is then
|
||||||
|
// the source of the configuration used in this module call, so
|
||||||
|
// we link to it directly
|
||||||
|
for {
|
||||||
|
parent, exists := m[parentKey]
|
||||||
|
if !exists {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p.parentKey = parentKey
|
||||||
|
parentKey = parent.parentKey
|
||||||
|
if parentKey == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m[key] = p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, marshal any other provider configs within the called module.
|
||||||
|
// It is safe to do this last because it is invalid to configure a
|
||||||
|
// provider which has passed provider configs in the module call.
|
||||||
marshalProviderConfigs(cc, schemas, m)
|
marshalProviderConfigs(cc, schemas, m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +401,9 @@ func marshalModuleCall(c *configs.Config, mc *configs.ModuleCall, schemas *terra
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.Expressions = marshalExpressions(mc.Config, schema)
|
ret.Expressions = marshalExpressions(mc.Config, schema)
|
||||||
module, _ := marshalModule(c, schemas, mc.Name)
|
|
||||||
|
module, _ := marshalModule(c, schemas, c.Path.String())
|
||||||
|
|
||||||
ret.Module = module
|
ret.Module = module
|
||||||
|
|
||||||
if len(mc.DependsOn) > 0 {
|
if len(mc.DependsOn) > 0 {
|
||||||
|
@ -342,11 +426,12 @@ func marshalModuleCall(c *configs.Config, mc *configs.ModuleCall, schemas *terra
|
||||||
func marshalResources(resources map[string]*configs.Resource, schemas *terraform.Schemas, moduleAddr string) ([]resource, error) {
|
func marshalResources(resources map[string]*configs.Resource, schemas *terraform.Schemas, moduleAddr string) ([]resource, error) {
|
||||||
var rs []resource
|
var rs []resource
|
||||||
for _, v := range resources {
|
for _, v := range resources {
|
||||||
|
providerConfigKey := opaqueProviderKey(v.ProviderConfigAddr().StringCompact(), moduleAddr)
|
||||||
r := resource{
|
r := resource{
|
||||||
Address: v.Addr().String(),
|
Address: v.Addr().String(),
|
||||||
Type: v.Type,
|
Type: v.Type,
|
||||||
Name: v.Name,
|
Name: v.Name,
|
||||||
ProviderConfigKey: opaqueProviderKey(v.ProviderConfigAddr().StringCompact(), moduleAddr),
|
ProviderConfigKey: providerConfigKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v.Mode {
|
switch v.Mode {
|
||||||
|
@ -416,6 +501,23 @@ func marshalResources(resources map[string]*configs.Resource, schemas *terraform
|
||||||
return rs, nil
|
return rs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flatten all resource provider keys in a module and its descendents, such
|
||||||
|
// that any resources from providers using a configuration passed through the
|
||||||
|
// module call have a direct refernce to that provider configuration.
|
||||||
|
func normalizeModuleProviderKeys(m *module, pcs map[string]providerConfig) {
|
||||||
|
for i, r := range m.Resources {
|
||||||
|
if pc, exists := pcs[r.ProviderConfigKey]; exists {
|
||||||
|
if _, hasParent := pcs[pc.parentKey]; hasParent {
|
||||||
|
m.Resources[i].ProviderConfigKey = pc.parentKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mc := range m.ModuleCalls {
|
||||||
|
normalizeModuleProviderKeys(&mc.Module, pcs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// opaqueProviderKey generates a unique absProviderConfig-like string from the module
|
// opaqueProviderKey generates a unique absProviderConfig-like string from the module
|
||||||
// address and provider
|
// address and provider
|
||||||
func opaqueProviderKey(provider string, addr string) (key string) {
|
func opaqueProviderKey(provider string, addr string) (key string) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
// FormatVersion represents the version of the json format and will be
|
// FormatVersion represents the version of the json format and will be
|
||||||
// incremented for any change to this format that requires changes to a
|
// incremented for any change to this format that requires changes to a
|
||||||
// consuming parser.
|
// consuming parser.
|
||||||
const FormatVersion = "1.0"
|
const FormatVersion = "1.1"
|
||||||
|
|
||||||
// Plan is the top-level representation of the json format of a plan. It includes
|
// Plan is the top-level representation of the json format of a plan. It includes
|
||||||
// the complete config and current state.
|
// the complete config and current state.
|
||||||
|
|
|
@ -576,6 +576,9 @@ func TestShow_json_output(t *testing.T) {
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(byteValue), &want)
|
json.Unmarshal([]byte(byteValue), &want)
|
||||||
|
|
||||||
|
// Disregard format version to reduce needless test fixture churn
|
||||||
|
want.FormatVersion = got.FormatVersion
|
||||||
|
|
||||||
if !cmp.Equal(got, want) {
|
if !cmp.Equal(got, want) {
|
||||||
t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
|
t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
|
||||||
}
|
}
|
||||||
|
@ -667,6 +670,9 @@ func TestShow_json_output_sensitive(t *testing.T) {
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(byteValue), &want)
|
json.Unmarshal([]byte(byteValue), &want)
|
||||||
|
|
||||||
|
// Disregard format version to reduce needless test fixture churn
|
||||||
|
want.FormatVersion = got.FormatVersion
|
||||||
|
|
||||||
if !cmp.Equal(got, want) {
|
if !cmp.Equal(got, want) {
|
||||||
t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
|
t.Fatalf("wrong result:\n %v\n", cmp.Diff(got, want))
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,7 @@
|
||||||
"provider_config": {
|
"provider_config": {
|
||||||
"test": {
|
"test": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test",
|
||||||
"expressions": {
|
"expressions": {
|
||||||
"region": {
|
"region": {
|
||||||
"constant_value": "somewhere"
|
"constant_value": "somewhere"
|
||||||
|
|
|
@ -152,6 +152,7 @@
|
||||||
"provider_config": {
|
"provider_config": {
|
||||||
"test": {
|
"test": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test",
|
||||||
"expressions": {
|
"expressions": {
|
||||||
"region": {
|
"region": {
|
||||||
"constant_value": "somewhere"
|
"constant_value": "somewhere"
|
||||||
|
|
|
@ -224,7 +224,7 @@
|
||||||
"mode": "managed",
|
"mode": "managed",
|
||||||
"type": "test_instance",
|
"type": "test_instance",
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"provider_config_key": "module_test_bar:test",
|
"provider_config_key": "module.module_test_bar:test",
|
||||||
"expressions": {
|
"expressions": {
|
||||||
"ami": {
|
"ami": {
|
||||||
"references": [
|
"references": [
|
||||||
|
@ -265,7 +265,7 @@
|
||||||
"mode": "managed",
|
"mode": "managed",
|
||||||
"type": "test_instance",
|
"type": "test_instance",
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"provider_config_key": "module_test_foo:test",
|
"provider_config_key": "module.module_test_foo:test",
|
||||||
"expressions": {
|
"expressions": {
|
||||||
"ami": {
|
"ami": {
|
||||||
"references": [
|
"references": [
|
||||||
|
@ -291,7 +291,8 @@
|
||||||
"provider_config": {
|
"provider_config": {
|
||||||
"module.module_test_foo:test": {
|
"module.module_test_foo:test": {
|
||||||
"module_address": "module.module_test_foo",
|
"module_address": "module.module_test_foo",
|
||||||
"name": "test"
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
"mode": "managed",
|
"mode": "managed",
|
||||||
"type": "test_instance",
|
"type": "test_instance",
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"provider_config_key": "more:test",
|
"provider_config_key": "module.my_module.module.more:test",
|
||||||
"expressions": {
|
"expressions": {
|
||||||
"ami": {
|
"ami": {
|
||||||
"references": [
|
"references": [
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
test = {
|
||||||
|
source = "hashicorp/test"
|
||||||
|
configuration_aliases = [test, test.second]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "test_primary" {
|
||||||
|
ami = "primary"
|
||||||
|
provider = test
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "test_secondary" {
|
||||||
|
ami = "secondary"
|
||||||
|
provider = test.second
|
||||||
|
}
|
||||||
|
|
||||||
|
module "grandchild" {
|
||||||
|
source = "./nested"
|
||||||
|
providers = {
|
||||||
|
test = test
|
||||||
|
test.alt = test.second
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
test = {
|
||||||
|
source = "hashicorp/test"
|
||||||
|
configuration_aliases = [test, test.alt]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "test_main" {
|
||||||
|
ami = "main"
|
||||||
|
provider = test
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "test_alternate" {
|
||||||
|
ami = "secondary"
|
||||||
|
provider = test.alt
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
provider "test" {
|
||||||
|
region = "somewhere"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "test" {
|
||||||
|
alias = "backup"
|
||||||
|
region = "elsewhere"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "test" {
|
||||||
|
ami = "foo"
|
||||||
|
provider = test
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "test_instance" "test_backup" {
|
||||||
|
ami = "foo-backup"
|
||||||
|
provider = test.backup
|
||||||
|
}
|
||||||
|
|
||||||
|
module "child" {
|
||||||
|
source = "./child"
|
||||||
|
providers = {
|
||||||
|
test = test
|
||||||
|
test.second = test.backup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module "sibling" {
|
||||||
|
source = "./child"
|
||||||
|
providers = {
|
||||||
|
test = test
|
||||||
|
test.second = test
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,567 @@
|
||||||
|
{
|
||||||
|
"format_version": "1.0",
|
||||||
|
"terraform_version": "1.1.0-dev",
|
||||||
|
"planned_values": {
|
||||||
|
"root_module": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "test_instance.test",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "foo"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_backup",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_backup",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "foo-backup"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"child_modules": [
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "module.child.test_instance.test_primary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_primary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "primary"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.child.test_instance.test_secondary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_secondary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"address": "module.child",
|
||||||
|
"child_modules": [
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "module.child.module.grandchild.test_instance.test_alternate",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_alternate",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.child.module.grandchild.test_instance.test_main",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_main",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "main"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"address": "module.child.module.grandchild"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "module.sibling.test_instance.test_primary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_primary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "primary"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.sibling.test_instance.test_secondary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_secondary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"address": "module.sibling",
|
||||||
|
"child_modules": [
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "module.sibling.module.grandchild.test_instance.test_alternate",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_alternate",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.sibling.module.grandchild.test_instance.test_main",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_main",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"schema_version": 0,
|
||||||
|
"values": {
|
||||||
|
"ami": "main"
|
||||||
|
},
|
||||||
|
"sensitive_values": {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"address": "module.sibling.module.grandchild"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resource_changes": [
|
||||||
|
{
|
||||||
|
"address": "module.child.module.grandchild.test_instance.test_alternate",
|
||||||
|
"module_address": "module.child.module.grandchild",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_alternate",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.child.module.grandchild.test_instance.test_main",
|
||||||
|
"module_address": "module.child.module.grandchild",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_main",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "main"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.child.test_instance.test_primary",
|
||||||
|
"module_address": "module.child",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_primary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "primary"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.child.test_instance.test_secondary",
|
||||||
|
"module_address": "module.child",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_secondary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.sibling.module.grandchild.test_instance.test_alternate",
|
||||||
|
"module_address": "module.sibling.module.grandchild",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_alternate",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.sibling.module.grandchild.test_instance.test_main",
|
||||||
|
"module_address": "module.sibling.module.grandchild",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_main",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "main"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.sibling.test_instance.test_primary",
|
||||||
|
"module_address": "module.sibling",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_primary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "primary"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "module.sibling.test_instance.test_secondary",
|
||||||
|
"module_address": "module.sibling",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_secondary",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "secondary"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "foo"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_backup",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_backup",
|
||||||
|
"provider_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"change": {
|
||||||
|
"actions": [
|
||||||
|
"create"
|
||||||
|
],
|
||||||
|
"before": null,
|
||||||
|
"after": {
|
||||||
|
"ami": "foo-backup"
|
||||||
|
},
|
||||||
|
"after_unknown": {
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"before_sensitive": false,
|
||||||
|
"after_sensitive": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration": {
|
||||||
|
"provider_config": {
|
||||||
|
"test": {
|
||||||
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"expressions": {
|
||||||
|
"region": {
|
||||||
|
"constant_value": "somewhere"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test.backup": {
|
||||||
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test",
|
||||||
|
"alias": "backup",
|
||||||
|
"expressions": {
|
||||||
|
"region": {
|
||||||
|
"constant_value": "elsewhere"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root_module": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "test_instance.test",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "foo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_backup",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_backup",
|
||||||
|
"provider_config_key": "test.backup",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "foo-backup"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"module_calls": {
|
||||||
|
"child": {
|
||||||
|
"source": "./child",
|
||||||
|
"module": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_primary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_primary",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "primary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_secondary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_secondary",
|
||||||
|
"provider_config_key": "test.backup",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "secondary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"module_calls": {
|
||||||
|
"grandchild": {
|
||||||
|
"source": "./nested",
|
||||||
|
"module": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_alternate",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_alternate",
|
||||||
|
"provider_config_key": "test.backup",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "secondary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_main",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_main",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "main"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sibling": {
|
||||||
|
"source": "./child",
|
||||||
|
"module": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_primary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_primary",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "primary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_secondary",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_secondary",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "secondary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"module_calls": {
|
||||||
|
"grandchild": {
|
||||||
|
"source": "./nested",
|
||||||
|
"module": {
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_alternate",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_alternate",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "secondary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "test_instance.test_main",
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "test_instance",
|
||||||
|
"name": "test_main",
|
||||||
|
"provider_config_key": "test",
|
||||||
|
"expressions": {
|
||||||
|
"ami": {
|
||||||
|
"constant_value": "main"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema_version": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -152,6 +152,7 @@
|
||||||
"provider_config": {
|
"provider_config": {
|
||||||
"test": {
|
"test": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test",
|
||||||
"version_constraint": ">= 1.2.3"
|
"version_constraint": ">= 1.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -152,6 +152,7 @@
|
||||||
"provider_config": {
|
"provider_config": {
|
||||||
"test": {
|
"test": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/test",
|
||||||
"expressions": {
|
"expressions": {
|
||||||
"region": {
|
"region": {
|
||||||
"constant_value": "somewhere"
|
"constant_value": "somewhere"
|
||||||
|
|
|
@ -323,7 +323,7 @@ Because the configuration models are produced at a stage prior to expression eva
|
||||||
// the configuration tree, flattened into a single map for convenience since
|
// the configuration tree, flattened into a single map for convenience since
|
||||||
// provider configurations are the one concept in Terraform that can span
|
// provider configurations are the one concept in Terraform that can span
|
||||||
// across module boundaries.
|
// across module boundaries.
|
||||||
"provider_configs": {
|
"provider_config": {
|
||||||
|
|
||||||
// Keys in the provider_configs map are to be considered opaque by callers,
|
// Keys in the provider_configs map are to be considered opaque by callers,
|
||||||
// and used just for lookups using the "provider_config_key" property in each
|
// and used just for lookups using the "provider_config_key" property in each
|
||||||
|
@ -333,6 +333,9 @@ Because the configuration models are produced at a stage prior to expression eva
|
||||||
// "name" is the name of the provider without any alias
|
// "name" is the name of the provider without any alias
|
||||||
"name": "aws",
|
"name": "aws",
|
||||||
|
|
||||||
|
// "full_name" is the fully-qualified provider name
|
||||||
|
"full_name": "registry.terraform.io/hashicorp/aws",
|
||||||
|
|
||||||
// "alias" is the alias set for a non-default configuration, or unset for
|
// "alias" is the alias set for a non-default configuration, or unset for
|
||||||
// a default configuration.
|
// a default configuration.
|
||||||
"alias": "foo",
|
"alias": "foo",
|
||||||
|
@ -378,7 +381,9 @@ Because the configuration models are produced at a stage prior to expression eva
|
||||||
|
|
||||||
// "provider_config_key" is the key into "provider_configs" (shown
|
// "provider_config_key" is the key into "provider_configs" (shown
|
||||||
// above) for the provider configuration that this resource is
|
// above) for the provider configuration that this resource is
|
||||||
// associated with.
|
// associated with. If the provider configuration was passed into
|
||||||
|
// this module from the parent module, the key will point to the
|
||||||
|
// original provider config block.
|
||||||
"provider_config_key": "opaque_provider_ref_aws",
|
"provider_config_key": "opaque_provider_ref_aws",
|
||||||
|
|
||||||
// "provisioners" is an optional field which describes any provisioners.
|
// "provisioners" is an optional field which describes any provisioners.
|
||||||
|
@ -440,7 +445,7 @@ Because the configuration models are produced at a stage prior to expression eva
|
||||||
// "module" is a representation of the configuration of the child module
|
// "module" is a representation of the configuration of the child module
|
||||||
// itself, using the same structure as the "root_module" object,
|
// itself, using the same structure as the "root_module" object,
|
||||||
// recursively describing the full module tree.
|
// recursively describing the full module tree.
|
||||||
"module": <module-configuration-representation>,
|
"module": <module-configuration-representation>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue