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.86k stars 9.21k forks source link

[Bug]: aws_servicecatalog_portfolio_share does not support sharing to GovCloud organization #39861

Open atheiman opened 1 month ago

atheiman commented 1 month ago

Terraform Core Version

latest

AWS Provider Version

v5.72.1

Affected Resource(s)

aws_servicecatalog_portfolio_share

Expected Behavior

Use aws_servicecatalog_portfolio_share to share a servicecatalog portfolio to a GovCloud organization (partition is aws-us-gov rather than aws) using either the organization arn or organization id.

# MUST BE RUN FROM A GOVCLOUD ORGANIZATION MANAGEMENT ACCOUNT TO REPRODUCE

resource "aws_servicecatalog_organizations_access" "svc_ctlg_orgs_access" {
  enabled = "true"
}

data "aws_organizations_organization" "current" {}

resource "aws_servicecatalog_portfolio" "portfolio" {
  name          = "Example Portfolio"
  description   = "Demo portfolio for service catalog products"
  provider_name = "Example Organization"
}

The above should be combined with one of the below options to be able to share to a govcloud organization by id or arn using the servicecatalog.CreatePortfolioShare api

# Option 1 - share to org by id
resource "aws_servicecatalog_portfolio_share" "org_id" {
  portfolio_id = aws_servicecatalog_portfolio.portfolio.id
  principal_id = data.aws_organizations_organization.current.id
  type         = "ORGANIZATION"
}

# Option 2 - share to org by arn
resource "aws_servicecatalog_portfolio_share" "org_arn" {
  portfolio_id = aws_servicecatalog_portfolio.portfolio.id
  principal_id = data.aws_organizations_organization.current.arn
  type         = "ORGANIZATION"
}

Actual Behavior

Option 1 (share by id) Fails

Sharing to govcloud organization by id gets blocked by the Terraform validation regex:

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: "principal_id" (o-52g4c5mxce) is an invalid ARN: arn: invalid prefix
│
│   with aws_servicecatalog_portfolio_share.org_id,
│   on portfolio.tf line 20, in resource "aws_servicecatalog_portfolio_share" "org_id":
│   20:   principal_id = data.aws_organizations_organization.current.id
│
╵
╷
│ Error: "principal_id" does not look like an OU or organization: "o-52g4c5mxce"
│
│   with aws_servicecatalog_portfolio_share.org_id,
│   on portfolio.tf line 20, in resource "aws_servicecatalog_portfolio_share" "org_id":
│   20:   principal_id = data.aws_organizations_organization.current.id
│
╵
╷
│ Error: "principal_id" doesn't look like AWS Account ID (exactly 12 digits): "o-52g4c5mxce"
│
│   with aws_servicecatalog_portfolio_share.org_id,
│   on portfolio.tf line 20, in resource "aws_servicecatalog_portfolio_share" "org_id":
│   20:   principal_id = data.aws_organizations_organization.current.id
│

Even though sharing to organization id works directly with the servicecatalog api:

aws servicecatalog create-portfolio-share \
  --portfolio-id 'port-aaaaaaaaaaaa' \
  --organization-node 'Type=ORGANIZATION,Value=o-aaaaaaaaaa'

Option 2 (share by arn) Fails

Sharing to govcloud organization by arn gets past the Terraform validation regex, but gets blocked by ServiceCatalog validation regex:

│ Error: creating Service Catalog Portfolio Share: operation error Service Catalog: CreatePortfolioShare, https response error
StatusCode: 400, RequestID: b4c17130-10cf-48d8-8730-178e09ed4354, api error ValidationException: 1 validation error
detected: Value 'arn:aws-us-gov:organizations::111111111111:organization/o-aaaaaaaaaa' at 'organizationNode.value' failed to
satisfy constraint: Member must satisfy regular expression pattern: (^[0-9]{12}$)|
(^arn:aws:organizations::\d{12}:organization\/o-[a-z0-9]{10,32})|(^o-[a-z0-9]{10,32}$)|(^arn:aws:organizations::\d{12}:ou\/o-
[a-z0-9]{10,32}\/ou-[0-9a-z]{4,32}-[0-9a-z]{8,32}$)|(^ou-[0-9a-z]{4,32}-[a-z0-9]{8,32}$)

More Info

servicecatalog.CreatePortfolioShare api accepts OrganizationNode.Value matching this regular expression: (^[0-9]{12}$)|(^arn:aws:organizations::\d{12}:organization\/o-[a-z0-9]{10,32})|(^o-[a-z0-9]{10,32}$)|(^arn:aws:organizations::\d{12}:ou\/o-[a-z0-9]{10,32}\/ou-[0-9a-z]{4,32}-[0-9a-z]{8,32}$)|(^ou-[0-9a-z]{4,32}-[a-z0-9]{8,32}$) which allows any of the following:

However, the aws_servicecatalog_portfolio_share terraform resource only allows ARNs for orgs and org units:

Unfortunately, the combination of Terraform aws_servicecatalog_portfolio_share requiring an arn, and servicecatalog.CreatePortfolioShare api only supporting aws partition in its validation, means aws_servicecatalog_portfolio_share cannot share with orgs or org units outside the aws partition (aws-us-gov for example)

ServiceCatalog api accepting only arn:aws: arns is a bug of course can't be fixed by the Terraform provider 😦 . But if the Terraform resource accepted org and org unit ids (rather than only ARNs), sharing would be possible with Terraform in GovCloud

Steps to Reproduce

From govcloud mgmt account: terraform plan / terraform apply

github-actions[bot] commented 1 month ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue