Skip to content

Commit

Permalink
Support multiple RAM principals (#19)
Browse files Browse the repository at this point in the history
* Support multiple RAM principals

Introduce new variable var.ram_principals, and deprecate
var.ram_principal. Deprecating rather than removing the old variable is
a lot more complex, code-wise, but the complexity is contained and
should ease the upgrade path for existing customers.

Fixes #14

* Auto Format

* Fix up var.ram_principals logic

* Make local.ram_principals a set, not tuple

* Update var.ram_principal docs

* Auto Format

Co-authored-by: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>
Co-authored-by: Andriy Knysh <aknysh@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 1, 2022
1 parent c31ec16 commit dd741e0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ Available targets:
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_ram_principal"></a> [ram\_principal](#input\_ram\_principal) | The principal to associate with the resource share. Possible values are an AWS account ID, an Organization ARN, or an Organization Unit ARN. If this is not provided and `ram_resource_share_enabled` is set to `true`, the Organization ARN will be used | `string` | `null` | no |
| <a name="input_ram_principal"></a> [ram\_principal](#input\_ram\_principal) | DEPRECATED, please use ram\_principals instead.<br><br>The principal to associate with the resource share. Possible values are an<br>AWS account ID, an Organization ARN, or an Organization Unit ARN. | `string` | `null` | no |
| <a name="input_ram_principals"></a> [ram\_principals](#input\_ram\_principals) | A list of principals to associate with the resource share. Possible values<br>are:<br><br>* AWS account ID<br>* Organization ARN<br>* Organization Unit ARN<br><br>If this (and var.ram\_principal) is not provided and<br>`ram_resource_share_enabled` is `true`, the Organization ARN will be used. | `list(string)` | `[]` | no |
| <a name="input_ram_resource_share_enabled"></a> [ram\_resource\_share\_enabled](#input\_ram\_resource\_share\_enabled) | Whether to enable sharing the Transit Gateway with the Organization using Resource Access Manager (RAM) | `bool` | `false` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_route_keys_enabled"></a> [route\_keys\_enabled](#input\_route\_keys\_enabled) | If true, Terraform will use keys to label routes, preventing unnecessary changes,<br>but this requires that the VPCs and subnets already exist before using this module.<br>If false, Terraform will use numbers to label routes, and a single change may<br>cascade to a long list of changes because the index or order has changed, but<br>this will work when the `true` setting generates the error `The "for_each" value depends on resource attributes...` | `bool` | `false` | no |
Expand Down
3 changes: 2 additions & 1 deletion docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_ram_principal"></a> [ram\_principal](#input\_ram\_principal) | The principal to associate with the resource share. Possible values are an AWS account ID, an Organization ARN, or an Organization Unit ARN. If this is not provided and `ram_resource_share_enabled` is set to `true`, the Organization ARN will be used | `string` | `null` | no |
| <a name="input_ram_principal"></a> [ram\_principal](#input\_ram\_principal) | DEPRECATED, please use ram\_principals instead.<br><br>The principal to associate with the resource share. Possible values are an<br>AWS account ID, an Organization ARN, or an Organization Unit ARN. | `string` | `null` | no |
| <a name="input_ram_principals"></a> [ram\_principals](#input\_ram\_principals) | A list of principals to associate with the resource share. Possible values<br>are:<br><br>* AWS account ID<br>* Organization ARN<br>* Organization Unit ARN<br><br>If this (and var.ram\_principal) is not provided and<br>`ram_resource_share_enabled` is `true`, the Organization ARN will be used. | `list(string)` | `[]` | no |
| <a name="input_ram_resource_share_enabled"></a> [ram\_resource\_share\_enabled](#input\_ram\_resource\_share\_enabled) | Whether to enable sharing the Transit Gateway with the Organization using Resource Access Manager (RAM) | `bool` | `false` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_route_keys_enabled"></a> [route\_keys\_enabled](#input\_route\_keys\_enabled) | If true, Terraform will use keys to label routes, preventing unnecessary changes,<br>but this requires that the VPCs and subnets already exist before using this module.<br>If false, Terraform will use numbers to label routes, and a single change may<br>cascade to a long list of changes because the index or order has changed, but<br>this will work when the `true` setting generates the error `The "for_each" value depends on resource attributes...` | `bool` | `false` | no |
Expand Down
18 changes: 15 additions & 3 deletions ram.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
locals {
ram_principals_provided = var.ram_principal != null || length(var.ram_principals) > 0
ram_principals = toset(var.ram_resource_share_enabled ? toset(
local.ram_principals_provided ? concat(
var.ram_principal == null ? [] : [var.ram_principal],
var.ram_principals,
) : [
data.aws_organizations_organization.default[0].arn
]
) : [])
}

# Resource Access Manager (RAM) share for the Transit Gateway
# https://docs.aws.amazon.com/ram/latest/userguide/what-is.html
resource "aws_ram_resource_share" "default" {
Expand All @@ -9,7 +21,7 @@ resource "aws_ram_resource_share" "default" {

# Share the Transit Gateway with the Organization if RAM principal was not provided
data "aws_organizations_organization" "default" {
count = var.ram_resource_share_enabled && (var.ram_principal == null || var.ram_principal == "") ? 1 : 0
count = var.ram_resource_share_enabled && ! local.ram_principals_provided ? 1 : 0
}

resource "aws_ram_resource_association" "default" {
Expand All @@ -19,7 +31,7 @@ resource "aws_ram_resource_association" "default" {
}

resource "aws_ram_principal_association" "default" {
count = var.ram_resource_share_enabled ? 1 : 0
principal = try(coalesce(var.ram_principal, data.aws_organizations_organization.default[0].arn), "")
for_each = local.ram_principals
principal = each.value
resource_share_arn = try(aws_ram_resource_share.default[0].id, "")
}
23 changes: 22 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,28 @@ variable "ram_resource_share_enabled" {
variable "ram_principal" {
type = string
default = null
description = "The principal to associate with the resource share. Possible values are an AWS account ID, an Organization ARN, or an Organization Unit ARN. If this is not provided and `ram_resource_share_enabled` is set to `true`, the Organization ARN will be used"
description = <<-EOT
DEPRECATED, please use ram_principals instead.
The principal to associate with the resource share. Possible values are an
AWS account ID, an Organization ARN, or an Organization Unit ARN.
EOT
}

variable "ram_principals" {
type = list(string)
default = []
description = <<-EOT
A list of principals to associate with the resource share. Possible values
are:
* AWS account ID
* Organization ARN
* Organization Unit ARN
If this (and var.ram_principal) is not provided and
`ram_resource_share_enabled` is `true`, the Organization ARN will be used.
EOT
}

variable "auto_accept_shared_attachments" {
Expand Down

0 comments on commit dd741e0

Please sign in to comment.