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.74k stars 9.1k forks source link

assume_role_policy not idempotent (or just bad policydoc?) #19349

Closed shawn-sterling closed 1 year ago

shawn-sterling commented 3 years ago

Community Note

Description

Hello Terraform friends.

I'm running the below code, and every time it runs it looks like something has changed, where it's just moving things around.

I've run with TF_LOG=TRACE and extracted the urlencoded value we are sending to AWS and it looks fine to me. If I paste that into the AWS web console it works fine. If I run with

aws iam update-assume-role-policy --role-name tmp-1 --policy-doc this_doc.json

it works fine.

I do see this warning in the trace logs (linked below)

2021/05/11 21:32:03 [WARN] Provider "registry.terraform.io/hashicorp/aws" produced an unexpected new value for aws_iam_role.this, but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:

The values are generated via terragrunt and we've tried jsonencoding the assume_role_policy as well, but that results in an error. The 2nd and 3rd policy were split out as a troubleshooting step, they used to be just 1; but this results in the same issue. Looks like a change being applied every time we run. Have also sorted the values generated for the accounts but this has no effect.

This could be bad policydoc, but I've applied via cli and webconsole and it goes in just fine.

Please halp. ;)

Terraform CLI and Terraform AWS Provider Version

Terraform v0.14.5
+ provider registry.terraform.io/hashicorp/aws v3.33.0
+ provider registry.terraform.io/hashicorp/external v2.1.0
+ provider registry.terraform.io/hashicorp/helm v2.0.3
+ provider registry.terraform.io/hashicorp/kubernetes v2.0.3
+ provider registry.terraform.io/hashicorp/local v2.1.0
+ provider registry.terraform.io/hashicorp/null v3.1.0
+ provider registry.terraform.io/hashicorp/random v3.1.0
+ provider registry.terraform.io/hashicorp/template v2.2.0

Affected Resource(s)

Terraform Configuration Files

Please include all Terraform configurations required to reproduce the bug. Bug reports without a functional reproduction may be closed without investigation.

#-- variables.tf:

variable "assume_role_policy" {
  description = "Assume role policies to attach to the IAM role"
}

variable "attach_policy_arns" {
  description = "Existing policy ARNs to attach to the IAM user"
  type        = list(string)
  default     = []
}

variable "custom_policy" {
  description = "Custom policies to create and attach to the IAM user"
  default     = []
  type        = list(string)
}

variable "custom_policy_name" {
  description = "custom policy name"
  default     = ""
}

variable "force_detach_policies" {
  description = "Whether policies should be detached from this role when destroying"
  type        = bool
  default     = false
}

variable "instance_profile_name" {
  description = "The instance profile name (optional)"
  type        = string
  default     = ""
}

variable "max_session_duration" {
  description = "Maximum CLI/API session duration in seconds between 3600 and 43200"
  type        = number
  default     = 3600
}

variable "role_description" {
  description = "IAM Role description"
  type        = string
  default     = ""
}

variable "role_name" {
  description = "Name of the IAM role"
  type        = string
}

variable "role_path" {
  description = "Path of the IAM role"
  default     = "/"
  type        = string
}

variable "role_permissions_boundary_arn" {
  description = "Permissions boundary ARN to use for IAM role"
  default     = ""
  type        = string
}

variable "tags" {
  description = "Tags applied to all resources"
  default     = {}
  type        = map(string)
}

# -- main.tf

resource "aws_iam_role" "this" {
  name                  = var.role_name
  path                  = var.role_path
  max_session_duration  = var.max_session_duration
  description           = var.role_description
  force_detach_policies = var.force_detach_policies
  permissions_boundary  = var.role_permissions_boundary_arn
  assume_role_policy    = var.assume_role_policy
  tags                  = var.tags
}

resource "aws_iam_policy" "this" {
  count  = length(var.custom_policy)
  name   = var.custom_policy_name
  policy = var.custom_policy[count.index]
}

locals {
  arns = concat(aws_iam_policy.this[*].arn, var.attach_policy_arns)
}

resource "aws_iam_role_policy_attachment" "this" {
  count      = length(local.arns)
  policy_arn = local.arns[count.index]
  role       = aws_iam_role.this.name
}

resource "aws_iam_instance_profile" "this" {
  count = length(var.instance_profile_name) > 0 ? 1 : 0
  name  = var.instance_profile_name
  role  = aws_iam_role.this.name
}

# test.json (account values have been changed)

{
  "assume_role_policy": "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"shedrivesmecrazy\",\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"AWS\": \"arn:aws:iam::000000000001:role/onelogin_ad_association\"\n      },\n      \"Action\": \"sts:AssumeRole\",\n      \"Condition\": {\n        \"ForAllValues:StringEqualsIgnoreCase\": {\n          \"SAML:sub\": [\n            \"fakename-network_Admin\",\n            \"fakename-network_Superadmin\",\n            \"fakename-network_Power\",\n            \"fakename-network_SysEng\",\n            \"fakename-network_Standard\"\n          ]\n        }\n      }\n    },\n    {\n      \"Sid\": \"likenooneelse\",\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"AWS\": [\n          \"arn:aws:iam::000000000001:role/GL-Admin\",\n          \"arn:aws:iam::000000000001:role/GL-NetEng\",\n          \"arn:aws:iam::000000000001:role/GL-Power\",\n          \"arn:aws:iam::000000000001:role/GL-Standard\",\n          \"arn:aws:iam::000000000001:role/GL-SysEng\",\n          \"arn:aws:iam::000000000001:role/GL-SuperAdmin\"\n        ]\n      },\n      \"Action\": \"sts:AssumeRole\"\n    },\n    {\n      \"Sid\": \"andicanthelpmyself\",\n      \"Effect\": \"Allow\",\n      \"Principal\": {\n        \"AWS\": [\n          \"arn:aws:iam::000000000002:root\",\n          \"arn:aws:iam::000000000003:root\",\n          \"arn:aws:iam::000000000004:root\",\n          \"arn:aws:iam::000000000005:root\",\n          \"arn:aws:iam::000000000006:root\",\n          \"arn:aws:iam::000000000007:root\",\n          \"arn:aws:iam::000000000001:root\",\n          \"arn:aws:iam::000000000008:root\",\n          \"arn:aws:iam::000000000009:root\",\n          \"arn:aws:iam::0000000000010:root\",\n          \"arn:aws:iam::0000000000011:root\",\n          \"arn:aws:iam::0000000000012:root\"\n        ]\n      },\n      \"Action\": \"sts:AssumeRole\"\n    }\n  ]\n}\n",
  "custom_policy": [
    "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"first\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:ListBucket\",\n        \"s3:GetBucketVersioning\"\n      ],\n      \"Resource\": \"arn:aws:s3:::fakename-terraform\"\n    },\n    {\n      \"Sid\": \"second\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:DeleteObject\",\n        \"s3:GetObject\",\n        \"s3:PutObject\"\n      ],\n      \"Resource\": \"arn:aws:s3:::fakename-terraform/*\"\n    }\n  ]\n}\n"
  ],
  "custom_policy_name": "terraform-usage-policy",
  "role_description": "terraform usage role",
  "role_name": "terraform-usage-role",
  "tags": {
    "owner": "test123@test.com"
  }
}

Debug Output

https://gist.github.com/shawn-sterling/a08655c9dc03e77b1806544fbf6c862f#file-tf-trace-log

Expected Behavior

terraform should create the role + assume role in a idempotent way so future runs do not look like they have changes.

Actual Behavior

Every time we run terraform it applies a "new" change (it moves around a few values).

Steps to Reproduce

  1. terraform apply -var-file test.json
  2. terraform apply -var-file test.json
  3. scratch head.

Important Factoids

N/A

References

N/A

stevehipwell commented 3 years ago

I'm seeing a very similar issue resulting from a complex use of aws_iam_policy_document resources which are tied back to json output.

github-actions[bot] commented 1 year ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

github-actions[bot] commented 1 year 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.