Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: Fix for missing provider requirements in JSON plan #27697

Merged
merged 1 commit into from
Feb 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 50 additions & 7 deletions command/jsonconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/internal/getproviders"
"github.com/hashicorp/terraform/terraform"
)

Expand Down Expand Up @@ -139,19 +140,61 @@ func marshalProviderConfigs(
return
}

// We want to determine only the provider requirements from this module,
// ignoring any descendants. Disregard any diagnostics when determining
// requirements because we want this marshalling to succeed even if there
// are invalid constraints.
reqs, _ := c.ProviderRequirementsShallow()

// Add an entry for each provider configuration block in the module.
for k, pc := range c.Module.ProviderConfigs {
providerFqn := c.ProviderForConfigAddr(addrs.LocalProviderConfig{LocalName: pc.Name})
schema := schemas.ProviderConfig(providerFqn)

p := providerConfig{
Name: pc.Name,
Alias: pc.Alias,
ModuleAddress: c.Path.String(),
Expressions: marshalExpressions(pc.Config, schema),
}

// Store the fully resolved provider version constraint, rather than
// using the version argument in the configuration block. This is both
// future proof (for when we finish the deprecation of the provider config
// version argument) and more accurate (as it reflects the full set of
// constraints, in case there are multiple).
if vc, ok := reqs[providerFqn]; ok {
p.VersionConstraint = getproviders.VersionConstraintsString(vc)
}

key := opaqueProviderKey(k, c.Path.String())

m[key] = p
}

// Ensure that any required providers with no associated configuration
// block are included in the set.
for k, pr := range c.Module.ProviderRequirements.RequiredProviders {
// If there exists a value for this provider, we have nothing to add
// to it, so skip.
key := opaqueProviderKey(k, 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, module address, and version
// constraints.
p := providerConfig{
Name: pc.Name,
Alias: pc.Alias,
ModuleAddress: c.Path.String(),
Expressions: marshalExpressions(pc.Config, schema),
VersionConstraint: pc.Version.Required.String(),
Name: pr.Name,
ModuleAddress: c.Path.String(),
}

if vc, ok := reqs[pr.Type]; ok {
p.VersionConstraint = getproviders.VersionConstraintsString(vc)
}
absPC := opaqueProviderKey(k, c.Path.String())

m[absPC] = p
m[key] = p
}

// Must also visit our child modules, recursively.
Expand Down
21 changes: 21 additions & 0 deletions command/testdata/show-json/provider-version-no-config/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
terraform {
required_providers {
test = {
source = "hashicorp/test"
version = ">= 1.2.3"
}
}
}

variable "test_var" {
default = "bar"
}

resource "test_instance" "test" {
ami = var.test_var
count = 3
}

output "test" {
value = var.test_var
}
184 changes: 184 additions & 0 deletions command/testdata/show-json/provider-version-no-config/output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{
"format_version": "0.1",
"variables": {
"test_var": {
"value": "bar"
}
},
"planned_values": {
"outputs": {
"test": {
"sensitive": false,
"value": "bar"
}
},
"root_module": {
"resources": [
{
"address": "test_instance.test[0]",
"index": 0,
"mode": "managed",
"type": "test_instance",
"name": "test",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "bar"
}
},
{
"address": "test_instance.test[1]",
"index": 1,
"mode": "managed",
"type": "test_instance",
"name": "test",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "bar"
}
},
{
"address": "test_instance.test[2]",
"index": 2,
"mode": "managed",
"type": "test_instance",
"name": "test",
"provider_name": "registry.terraform.io/hashicorp/test",
"schema_version": 0,
"values": {
"ami": "bar"
}
}
]
}
},
"prior_state": {
"format_version": "0.1",
"values": {
"outputs": {
"test": {
"sensitive": false,
"value": "bar"
}
},
"root_module": {}
}
},
"resource_changes": [
{
"address": "test_instance.test[0]",
"index": 0,
"mode": "managed",
"type": "test_instance",
"provider_name": "registry.terraform.io/hashicorp/test",
"name": "test",
"change": {
"actions": [
"create"
],
"before": null,
"after_unknown": {
"id": true
},
"after": {
"ami": "bar"
}
}
},
{
"address": "test_instance.test[1]",
"index": 1,
"mode": "managed",
"type": "test_instance",
"provider_name": "registry.terraform.io/hashicorp/test",
"name": "test",
"change": {
"actions": [
"create"
],
"before": null,
"after_unknown": {
"id": true
},
"after": {
"ami": "bar"
}
}
},
{
"address": "test_instance.test[2]",
"index": 2,
"mode": "managed",
"type": "test_instance",
"provider_name": "registry.terraform.io/hashicorp/test",
"name": "test",
"change": {
"actions": [
"create"
],
"before": null,
"after_unknown": {
"id": true
},
"after": {
"ami": "bar"
}
}
}
],
"output_changes": {
"test": {
"actions": [
"create"
],
"before": null,
"after": "bar",
"after_unknown": false
}
},
"configuration": {
"provider_config": {
"test": {
"name": "test",
"version_constraint": ">= 1.2.3"
}
},
"root_module": {
"outputs": {
"test": {
"expression": {
"references": [
"var.test_var"
]
}
}
},
"resources": [
{
"address": "test_instance.test",
"mode": "managed",
"type": "test_instance",
"name": "test",
"provider_config_key": "test",
"schema_version": 0,
"expressions": {
"ami": {
"references": [
"var.test_var"
]
}
},
"count_expression": {
"constant_value": 3
}
}
],
"variables": {
"test_var": {
"default": "bar"
}
}
}
}
}
26 changes: 26 additions & 0 deletions command/testdata/show-json/provider-version/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
terraform {
required_providers {
test = {
source = "hashicorp/test"
version = ">= 1.2.3"
}
}
}

provider "test" {
region = "somewhere"
version = "1.2.3"
}

variable "test_var" {
default = "bar"
}

resource "test_instance" "test" {
ami = var.test_var
count = 3
}

output "test" {
value = var.test_var
}
Loading