hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.71k stars 9.55k forks source link

panic: inconsistent list element types #24229

Closed garthk closed 4 years ago

garthk commented 4 years ago

Terraform Version

Terraform v0.12.21

Terraform Configuration Files, Debug Output, Crash Output

I regret I can't post these in public and lack the time right now to redact them.

Expected Behavior

It would have been nice if terraform apply had succeeded.

Actual Behavior

panic: inconsistent list element types (cty.Object(map[string]cty.Type{"Action":cty.String, "Condition":cty.DynamicPseudoType, "Effect":cty.String, "Principal":cty.Map(cty.String), "Sid":cty.String}) then cty.Object(map[string]cty.Type{"Action":cty.String, "Condition":cty.Object(map[string]cty.Type{"Bool":cty.Object(map[string]cty.Type{"aws:MultiFactorAuthPresent":cty.String})}), "Effect":cty.String, "Principal":cty.Map(cty.String), "Sid":cty.String}))

goroutine 650 [running]:
github.com/zclconf/go-cty/cty.ListVal(0xc00151e480, 0x2, 0x2, 0xc00136b110, 0xc0012aa420, 0x1, 0x1)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/value_init.go:166 +0x436
github.com/zclconf/go-cty/cty/convert.conversionTupleToList.func2(0x2eea3a0, 0xc0003a2ec0, 0x2620420, 0xc0003a2f00, 0xc0012aa420, 0x1, 0x1, 0xc0003a2fe0, 0x2eea3a0, 0xc0003a2f60, ...)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/convert/conversion_collection.go:267 +0x53f
github.com/zclconf/go-cty/cty/convert.getConversion.func1(0x2eea3a0, 0xc0003a2ec0, 0x2620420, 0xc0003a2f00, 0x0, 0x0, 0x0, 0x2630a20, 0x3d1cba1, 0x2eea220, ...)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/convert/conversion.go:46 +0x1ab
github.com/zclconf/go-cty/cty/convert.retConversion.func1(0x2eea3a0, 0xc0003a2ec0, 0x2620420, 0xc0003a2f00, 0x0, 0x0, 0x0, 0x0, 0x2630a20, 0x3d1cba1)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/pkg/mod/github.com/zclconf/go-cty@v1.2.1/cty/convert/conversion.go:179 +0x6b
github.com/hashicorp/hcl/v2/hclsyntax.(*ConditionalExpr).Value(0xc00043f810, 0xc0003a2e60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/pkg/mod/github.com/hashicorp/hcl/v2@v2.3.0/hclsyntax/expression.go:574 +0x11de
github.com/hashicorp/hcl/v2/hclsyntax.(*ObjectConsExpr).Value(0xc0006ac3c0, 0xc0003a2e60, 0x0, 0xc000c8b600, 0x1, 0x1, 0x0, 0x0, 0x0)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/pkg/mod/github.com/hashicorp/hcl/v2@v2.3.0/hclsyntax/expression.go:744 +0x288
github.com/hashicorp/terraform/lang.(*Scope).EvalExpr(0xc0014631d0, 0x4723da8, 0xc0006ac3c0, 0x2eea260, 0x3e6cb70, 0x0, 0x0, 0xc000c8b7b8, 0x1, 0x1, ...)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/lang/eval.go:95 +0x1b3
github.com/hashicorp/terraform/terraform.(*BuiltinEvalContext).EvaluateExpr(0xc00103f520, 0x4723da8, 0xc0006ac3c0, 0x2eea260, 0x3e6cb70, 0x0, 0x0, 0x0, 0xc000f48910, 0x10cb241, ...)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/terraform/eval_context_builtin.go:279 +0x1e2
github.com/hashicorp/terraform/terraform.(*EvalLocal).Eval(0xc000413580, 0x2f1baa0, 0xc00103f520, 0x2, 0x2, 0x1b53c4d, 0x2760280)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/terraform/eval_local.go:43 +0x6fc
github.com/hashicorp/terraform/terraform.EvalRaw(0x2ea5c40, 0xc000413580, 0x2f1baa0, 0xc00103f520, 0x26dd6c0, 0x3d1cba4, 0x2645c20, 0xc00168dee0)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/terraform/eval.go:57 +0x131
github.com/hashicorp/terraform/terraform.Eval(0x2ea5c40, 0xc000413580, 0x2f1baa0, 0xc00103f520, 0xc000413580, 0x2ea5c40, 0xc000413580, 0x0)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/terraform/eval.go:35 +0x4d
github.com/hashicorp/terraform/terraform.(*Graph).walk.func1(0x287df20, 0xc001a5a180, 0x0, 0x0, 0x0)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/terraform/graph.go:90 +0xf7e
github.com/hashicorp/terraform/dag.(*Walker).walkVertex(0xc000c6fa80, 0x287df20, 0xc001a5a180, 0xc00151f500)
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/dag/walk.go:392 +0x377
created by github.com/hashicorp/terraform/dag.(*Walker).Update
    /private/tmp/terraform-20200220-93988-12qgkfs/terraform-0.12.21/src/github.com/hashicorp/terraform/dag/walk.go:314 +0xaa7

Steps to Reproduce

garthk commented 4 years ago

It's not quite #21588 because I'm not within cooee of a module output.

Figured out it's to do with the gymnastics I'm having to pull to add an extra statement to an assume_role_policy only if an input variable is set:

locals {
  assume_by_lambda = {
    Sid    = "AssumeByLambda"
    Effect = "Allow"
    Principal = {
      Service = "lambda.amazonaws.com"
    }
    Action = "sts:AssumeRole"
    Condition = {
      NotIpAddress = {
        "aws:SourceIp" = "127.0.0.1/32"
      }
    }
  }
  assume_by_account = {
    Sid    = "AssumeByIAMInSameAccount"
    Effect = "Allow"
    Principal = {
      AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
    }
    Action = "sts:AssumeRole"
    Condition = {
      Bool = {
        "aws:MultiFactorAuthPresent" = "true"
      }
    }
  }
  assume_role_policy = {
    Version   = "2012-10-17"
    Statement = var.account_may_assume ? [local.assume_by_lambda, local.assume_by_account] : [local.assume_by_lambda]
  }
}

resource "aws_iam_role" "lambda" {
  name               = var.name
  assume_role_policy = jsonencode(local.assume_role_policy)
}

If I remove the dummy Condition from assume_by_lambda, I get:

Error: Inconsistent conditional result types

  on ../modules/mymodule/main.tf line 32, in locals:
  32:     Statement = var.account_may_assume ? [local.assume_by_lambda, local.assume_by_account] : [local.assume_by_lambda]
    |----------------
    | local.assume_by_account is object with 5 attributes
    | local.assume_by_lambda is object with 4 attributes

If I set Condition = null and account_may_assume is true, I get the crash above.

danieldreier commented 4 years ago

I believe this is actually the same issue as was reproduced in https://github.com/hashicorp/terraform/issues/21588#issuecomment-592149310 because the error message is the same and it also occurs in github.com/zclconf/go-cty/cty.ListVal. Since that issue has an easier reproduction case that I believe is the same underlying bug, I'm going to close this in favor of that one. @garthk if you are really confident this is a different one please email me at ddreier@hashicorp.com and I'm happy to re-open this and then we can re-test once the other one is fixed.

ghost commented 4 years ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.