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.77k stars 9.12k forks source link

[Bug]: #26878

Open n3mawashi opened 2 years ago

n3mawashi commented 2 years ago

Terraform Core Version

0.1.12

AWS Provider Version

4.20.1

Affected Resource(s)

Hi - I ran into a minor bug where aws_backup_framework always expects the input parameter value to be a string. This problem is that this control requires a list or ARNs as per AWS documentation of https://docs.aws.amazon.com/config/latest/developerguide/backup-recovery-point-manual-deletion-disabled.html

To reproduce the bug

resource "aws_backup_framework" "example_framework" {
  control {
    name = "BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED"
      input_parameter {
        name = "principalArnList" 
        value = [
          "arn:aws:iam::*:role/SysAdminRole",
         "arn:aws:iam::*:role/OtherRole"
      ]
   }
}

This produces an error

Error: Incorrect attribute value type
│
│   on ../modules/backup/backup-audit.tf line 6, in resource "aws_backup_framework" "example":
│   6:       value = ["arn:aws:iam::*:role/SysAdminRole", "arn:aws:iam::*:role/OtherRole"]
│
│ Inappropriate value for attribute "value": string required.

If I try to craft a string with escaped square bracket and commas I get the following message from the AWS API

Error: error updating Backup Framework (example): InvalidParameterValueException: Invalid value for the parameter principalArnList in control BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED. Expected comma-separated list of valid IAM principal ARNs.
│ {
│   RespMetadata: {
│     StatusCode: 400,
│     RequestID: "c1ed3eb5-f13f-4801-97fe-b900ae609f03"
│   },
│   Message_: "Invalid value for the parameter principalArnList in control BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED. Expected comma-separated list of valid IAM principal ARNs."
│ }

I think the issue stems from the following: https://github.com/hashicorp/terraform-provider-aws/blob/main/internal/service/backup/framework.go#L56

My go experience is nonexistent, but I'll try to come up with a solution.

Expected Behavior

For the ARN list to be applied as input a parameter

Actual Behavior

Errors

Error: Incorrect attribute value type
│
│   on ../modules/backup/backup-audit.tf line 6, in resource "aws_backup_framework" "example":
│   6:       value = ["arn:aws:iam::*:role/SysAdminRole", "arn:aws:iam::*:role/OtherRole"]
│
│ Inappropriate value for attribute "value": string required.

Relevant Error/Panic Output Snippet

No response

Terraform Configuration Files

resource "aws_backup_framework" "example_framework" {
  control {
    name = "BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED"
      input_parameter {
        name = "principalArnList" 
        value = [
          "arn:aws:iam::*:role/SysAdminRole",
         "arn:aws:iam::*:role/OtherRole"
      ]
   }
}

Steps to Reproduce

  1. Add the above code to main.tf with provider code
  2. assume a role.
  3. run tf plan

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

No

github-actions[bot] commented 2 years ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

justinretzolk commented 2 years ago

Hey @n3mawashi 👋 Thank you for taking the time to raise this! I believe the issue you're seeing here is that you're trying to pass multiple values to a single input_parameter. If you instead break them up into multiple input_parameter blocks, they should merge with the result that you're expecting. This would look something like the following (full disclosure: I'm not able to easily test this to verify, and have based this off of double checking the documentation and schema):

resource "aws_backup_framework" "example_framework" {
  name = "example-framework"

  control {
    name = "BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED"

    input_parameter {
      name = "principalArnList" 
      value = "arn:aws:iam::*:role/SysAdminRole"
    }

    input_parameter {
      name = "principalArnList" 
      value = "arn:aws:iam::*:role/OtherRole"
    }
  }
}
n3mawashi commented 2 years ago

Thanks, @justinretzolk for the quick reply. Unfortunately, that hasn't worked. still getting the same error of

 Error: error updating Backup Framework (icare_uat_compliance_framework): InvalidParameterValueException: Invalid value for the parameter principalArnList in control BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED. Expected comma-separated list of valid IAM principal ARNs.
│ {
│   RespMetadata: {
│     StatusCode: 400,
│     RequestID: "4b6d4489-67e4-4648-9e00-dc22847cbf15"
│   },
│   Message_: "Invalid value for the parameter principalArnList in control BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED. Expected comma-separated list of valid IAM principal ARNs."
│ }
│ 
│   with module.backup.aws_backup_framework.compliance_framework[0],
│   on ../modules/backup/backup-audit.tf line 1, in resource "aws_backup_framework" "compliance_framework":
│    1: resource "aws_backup_framework" "compliance_framework" {
│ 
╵
n3mawashi commented 2 years ago

here is the modify control code that I used


  control {
    name = "BACKUP_RECOVERY_POINT_MANUAL_DELETION_DISABLED"
    input_parameter {
      name = "principalArnList" 
      value = "arn:aws:iam::*:role/SysAdminRole"
    }
    input_parameter {
      name = "principalArnList" 
      value = "arn:aws:iam::*:role/OtherAdmin"  
    }

    scope {
      tags = {
        name = var.backup_tag_selection
        value = "true"
      }
    }
  }
}
justinretzolk commented 2 years ago

Hey @n3mawashi 👋 Thank you for the followup, and again, sorry that I'm not able to easily test this to have caught that error! I did a bit more digging and found that I was mistaken about the multiple input_parameter blocks merging since they had the same name value -- that does not appear to happen.

I did a bit of additional testing, ran the following through terraform validate, and it passed, so I suspect it may work. The key thing here was that the input_parameter.value is a string, so will pass Terraform validation. The underlying Go Type in the SDK expects as string as well, so my assumption here is that the API receives this as a string and then converts it. I'm unsure of whether the API expects the ARNs in the list to be wrapped in (escaped) quotes or not, so I provided examples of each way below.

Without wrapping the ARNs in quotes:

    input_parameter {
      name = "principalArnList" 
      value = "[arn:aws:iam::*:role/SysAdminRole, arn:aws:iam::*:role/OtherRole]"
    }

Wrapping the ARNs in quotes:

    input_parameter {
      name = "principalArnList" 
      value = "[\"arn:aws:iam::*:role/SysAdminRole\", \"arn:aws:iam::*:role/OtherRole\"]"
    }
mattburgess commented 2 years ago

Just to interject here, but I think the docs the OP linked to actually state what it's after, which is just a CSV string, so I reckon this should work:

    input_parameter {
      name = "principalArnList" 
      value = "arn:aws:iam::*:role/SysAdminRole,arn:aws:iam::*:role/OtherRole"
    }
github-actions[bot] commented 1 week 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!