hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.84k stars 9.19k forks source link

[Bug]: not a JSON object when using mock providers with terraform test #36700

Open wf-aw opened 7 months ago

wf-aw commented 7 months ago

Terraform Core Version

1.7.5

AWS Provider Version

5.43.0, 5.21.0

Affected Resource(s)

aws_iam_role assume_role_policy

Expected Behavior

When running a terraform test using the mock_provider block added in terraform 1.7, it should create proper fake data or accept faked data for resource/data lookups. For the aws_iam_policy_document data source, I would assume it would accept the converted json since it doesn't need to look anything up.

I even tried every iteration of the override_data block (at the file level, in the run block, and in the provider block with and without the policy fed to it).

Actual Behavior

Running tests with mock providers will generate invalid JSON policy errors. I have even tried using the override_data block and it still returns the same error.

Relevant Error/Panic Output Snippet

Error: "assume_role_policy" contains an invalid JSON policy: not a JSON object
Error: "policy" contains an invalid JSON policy: not a JSON object

Terraform Configuration Files

Terraform test file

mock_provider "aws" {
  alias = "fake"
  override_data {
    target = module.REDACTED.data.aws_iam_policy_document.assume_role_policy
    values = {
      body = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"ecs-tasks.amazonaws.com\"},\"Effect\":\"Allow\",\"Sid\":\"AllowECSAssumeRole\"}]}"
     }
  } 
}
#override_data {
#  target = module.REDACTED.data.aws_iam_policy_document.assume_role_policy
#} 
run "test" {
  command = plan
  providers = {
    aws = aws.fake
  }
  module {
    source = "REDACTED" //resources below exist in this module
  }
  assert {
    condition     = length(data.aws_iam_policy_document.assume_role_policy.json) < 6144
    error_message = "Length of IAM policy assume_role_policy is too long"
  }
}

Providers and resources

terraform {
  required_version = ">=1.7.5"

  required_providers {
      aws = {
        source  = "hashicorp/aws"
        version = "~>5.43.0"
      }
    }
  }

data "aws_iam_policy_document" "assume_role_policy" {
  statement {
    sid    = "AllowECSAssumeRole"
    effect = "Allow"
    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "iam_role" {
  name_prefix             = local.name_prefix
  assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json

  tags = local.tags
}

Steps to Reproduce

Either remove all override_data blocks or place in any support location Run terraform test

Debug Output

No response

Panic Output

No response

Important Factoids

These resources create valid JSON and there are other examples from the same repo where policies using the iam_policy_document data source (which all have been applied perviously thus proving they create valid JSON) also produce the same error.

I am using the mock_provider here because I recently added cross account data lookups to the code and those fail the standard tests because the provider is trying to use the fake credentials to do real lookups against the resources, also causing the tests to fail.

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 7 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

will-schneble commented 5 months ago

AWS data sources have placeholder data when using terraform test. This makes sense for a lot of data sources such as data.aws_vpc, data.aws_security_groups, etc. For example, data.aws_vpc.this.cidr_block by default will be a random string like "uklbdtcf". However for data.aws_iam_policy_document it would be much more convenient if it was computed because currently:

  1. Users have to define valid JSON overrides, which is tedious, or other resources will fail on validation such as aws_iam_role trust policies
  2. We cannot test the computed policy document
ankitjhingan commented 4 months ago

even am getting same error while running the tests on a submodule.

I am using terraform v1.8.3

│ Error: "assume_role_policy" contains an invalid JSON policy: not a JSON object
│
│   with module.eks_managed_node_group["global-ondemand-ng"].aws_iam_role.this[0],
│   on .terraform/modules/eks_managed_node_group/modules/eks-managed-node-group/main.tf line 510, in resource "aws_iam_role" "this":
│  510:   assume_role_policy    = data.aws_iam_policy_document.assume_role_policy[0].json