Skip to content

Commit

Permalink
feat: Allow array of Org IDs (#97)
Browse files Browse the repository at this point in the history
Set org id as a list to allow multiple orgs in the same AWS account

Result of tf plan on an existing apply

```
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.sn_managed_cloud.aws_iam_role.bootstrap_role[0] will be updated in-place
  ~ resource "aws_iam_role" "bootstrap_role" {
      ~ assume_role_policy    = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Condition = {
                          + "ForAllValues:StringEquals" = {
                              + "sts:ExternalId" = [
                                  + "o-nd3gv",
                                  + "o-z7cmp",
                                ]
                            }
                          - StringEquals                = {
                              - "sts:ExternalId" = "o-nd3gv"
                            }
                        }
                        # (4 unchanged attributes hidden)
                    },
                  ~ {
                      ~ Condition = {
                          + "ForAllValues:StringEquals" = {
                              + "sts:ExternalId" = [
                                  + "o-nd3gv",
                                  + "o-z7cmp",
                                ]
                            }
                          - StringEquals                = {
                              - "sts:ExternalId" = "o-nd3gv"
                            }
                        }
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = "sts:AssumeRoleWithWebIdentity"
                        Condition = {
                            StringEquals = {
                                "accounts.google.com:aud" = "108050666045451143798"
                            }
                        }
                        Effect    = "Allow"
                        Principal = {
                            Federated = "accounts.google.com"
                        }
                        Sid       = "AllowStreamNativeControlPlaneAccess"
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        id                    = "StreamNativeCloudBootstrapRole"
        name                  = "StreamNativeCloudBootstrapRole"
        tags                  = {
            "SNVersion" = "3.14.1"
            "Vendor"    = "StreamNative"
        }
        # (10 unchanged attributes hidden)
    }

  # module.sn_managed_cloud.aws_iam_role.management_role will be updated in-place
  ~ resource "aws_iam_role" "management_role" {
      ~ assume_role_policy    = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Condition = {
                          + "ForAllValues:StringEquals" = {
                              + "sts:ExternalId" = [
                                  + "o-nd3gv",
                                  + "o-z7cmp",
                                ]
                            }
                          - StringEquals                = {
                              - "sts:ExternalId" = "o-nd3gv"
                            }
                        }
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = "sts:AssumeRoleWithWebIdentity"
                        Condition = {
                            StringEquals = {
                                "accounts.google.com:aud" = "108050666045451143798"
                            }
                        }
                        Effect    = "Allow"
                        Principal = {
                            Federated = "accounts.google.com"
                        }
                        Sid       = "AllowStreamNativeControlPlaneAccess"
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        id                    = "StreamNativeCloudManagementRole"
        name                  = "StreamNativeCloudManagementRole"
        tags                  = {
            "SNVersion" = "3.14.1"
            "Vendor"    = "StreamNative"
        }
        # (10 unchanged attributes hidden)
    }

Plan: 0 to add, 2 to change, 0 to destroy.
```


### Apply results
```
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # module.sn_managed_cloud.aws_iam_role.bootstrap_role[0] will be updated in-place
  ~ resource "aws_iam_role" "bootstrap_role" {
      ~ assume_role_policy    = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Condition = {
                          + "ForAllValues:StringEquals" = {
                              + "sts:ExternalId" = [
                                  + "o-nd3gv",
                                  + "o-z7cmp",
                                ]
                            }
                          - StringEquals                = {
                              - "sts:ExternalId" = "o-nd3gv"
                            }
                        }
                        # (4 unchanged attributes hidden)
                    },
                  ~ {
                      ~ Condition = {
                          + "ForAllValues:StringEquals" = {
                              + "sts:ExternalId" = [
                                  + "o-nd3gv",
                                  + "o-z7cmp",
                                ]
                            }
                          - StringEquals                = {
                              - "sts:ExternalId" = "o-nd3gv"
                            }
                        }
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = "sts:AssumeRoleWithWebIdentity"
                        Condition = {
                            StringEquals = {
                                "accounts.google.com:aud" = "108050666045451143798"
                            }
                        }
                        Effect    = "Allow"
                        Principal = {
                            Federated = "accounts.google.com"
                        }
                        Sid       = "AllowStreamNativeControlPlaneAccess"
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        id                    = "StreamNativeCloudBootstrapRole"
        name                  = "StreamNativeCloudBootstrapRole"
        tags                  = {
            "SNVersion" = "3.14.1"
            "Vendor"    = "StreamNative"
        }
        # (10 unchanged attributes hidden)
    }

  # module.sn_managed_cloud.aws_iam_role.management_role will be updated in-place
  ~ resource "aws_iam_role" "management_role" {
      ~ assume_role_policy    = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Condition = {
                          + "ForAllValues:StringEquals" = {
                              + "sts:ExternalId" = [
                                  + "o-nd3gv",
                                  + "o-z7cmp",
                                ]
                            }
                          - StringEquals                = {
                              - "sts:ExternalId" = "o-nd3gv"
                            }
                        }
                        # (4 unchanged attributes hidden)
                    },
                    {
                        Action    = "sts:AssumeRoleWithWebIdentity"
                        Condition = {
                            StringEquals = {
                                "accounts.google.com:aud" = "108050666045451143798"
                            }
                        }
                        Effect    = "Allow"
                        Principal = {
                            Federated = "accounts.google.com"
                        }
                        Sid       = "AllowStreamNativeControlPlaneAccess"
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        id                    = "StreamNativeCloudManagementRole"
        name                  = "StreamNativeCloudManagementRole"
        tags                  = {
            "SNVersion" = "3.14.1"
            "Vendor"    = "StreamNative"
        }
        # (10 unchanged attributes hidden)
    }

Plan: 0 to add, 2 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.sn_managed_cloud.aws_iam_role.bootstrap_role[0]: Modifying... [id=StreamNativeCloudBootstrapRole]
module.sn_managed_cloud.aws_iam_role.management_role: Modifying... [id=StreamNativeCloudManagementRole]
module.sn_managed_cloud.aws_iam_role.bootstrap_role[0]: Modifications complete after 0s [id=StreamNativeCloudBootstrapRole]
module.sn_managed_cloud.aws_iam_role.management_role: Modifications complete after 1s [id=StreamNativeCloudManagementRole]

Apply complete! Resources: 0 added, 2 changed, 0 destroyed.
```
  • Loading branch information
mitch-hamm authored Nov 20, 2024
1 parent 9c404c0 commit 3990b48
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
20 changes: 18 additions & 2 deletions modules/aws/vendor-access/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@ module "sn_managed_cloud" {
}
```

Or if using multiple orgs

```hcl
provider "aws" {
region = <YOUR_REGION>
}
module "sn_managed_cloud" {
source = "github.com/streamnative/terraform-managed-cloud//modules/aws/vendor-access?ref=<LATEST_GIT_TAG>"
external_ids = ["<YOUR_SNCLOUD_ORG_ID>", "<YOUR_SNCLOUD_ORG_ID>"]
}
```

After [authenticating to your AWS account](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration) execute the following sequence of commands from the directory containing the `main.tf` configuration file:

1. Run `terraform init`
Expand Down Expand Up @@ -136,8 +151,9 @@ No modules.
| <a name="input_ebs_kms_key_arns"></a> [ebs\_kms\_key\_arns](#input\_ebs\_kms\_key\_arns) | Sets the list of allowed kms key arns, if not set, uses the default ebs kms key | `list(any)` | `[]` | no |
| <a name="input_eks_cluster_pattern"></a> [eks\_cluster\_pattern](#input\_eks\_cluster\_pattern) | Defines the eks clsuter prefix for streamnative clusters. This should normally remain the default value. | `string` | `"*snc*"` | no |
| <a name="input_enforce_vendor_federation"></a> [enforce\_vendor\_federation](#input\_enforce\_vendor\_federation) | Do not enable this unless explicitly told to do so by StreamNative. Restrict access for the streamnative\_vendor\_access\_role\_arns to only federated Google accounts. Intended to be true by default in the future. | `bool` | `false` | no |
| <a name="input_external_id"></a> [external\_id](#input\_external\_id) | A external ID that correspond to your Organization within StreamNative Cloud, used for all STS assume role calls to the IAM roles created by the module. This will be the organization ID in the StreamNative console, e.g. "o-xhopj". | `string` | n/a | yes |
| <a name="input_hosted_zone_allowed_ids"></a> [hosted\_zone\_allowed\_ids](#input\_hosted\_zone\_allowed\_ids) | Allows for further scoping down policy for allowed hosted zones. The IDs provided are constructed into ARNs | `list(any)` | <pre>[<br> "*"<br>]</pre> | no |
| <a name="input_external_id"></a> [external\_id](#input\_external\_id) | A external ID that correspond to your Organization within StreamNative Cloud, used for all STS assume role calls to the IAM roles created by the module. This will be the organization ID in the StreamNative console, e.g. "o-xhopj". | `string` | `""` | no |
| <a name="input_external_ids"></a> [external\_ids](#input\_external\_ids) | A list of external IDs that correspond to your Organization within StreamNative Cloud, used for all STS assume role calls to the IAM roles created by the module. This will be the organization ID in the StreamNative console, e.g. "o-xhopj". | `list(string)` | `[]` | no |
| <a name="input_hosted_zone_allowed_ids"></a> [hosted\_zone\_allowed\_ids](#input\_hosted\_zone\_allowed\_ids) | Allows for further scoping down policy for allowed hosted zones. The IDs provided are constructed into ARNs | `list(any)` | <pre>[<br/> "*"<br/>]</pre> | no |
| <a name="input_region"></a> [region](#input\_region) | The AWS region where your instance of StreamNative Cloud is deployed. Defaults to all regions "*" | `string` | `"*"` | no |
| <a name="input_s3_bucket_pattern"></a> [s3\_bucket\_pattern](#input\_s3\_bucket\_pattern) | Defines the bucket prefix for streamnative managed buckets (backup and offload). Typically defaults to "snc-*", but should match the bucket created using the tiered-storage-resources module | `string` | `"*snc*"` | no |
| <a name="input_s3_kms_key_arns"></a> [s3\_kms\_key\_arns](#input\_s3\_kms\_key\_arns) | List of KMS key ARNs to use for S3 buckets | `list(string)` | `[]` | no |
Expand Down
5 changes: 3 additions & 2 deletions modules/aws/vendor-access/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ locals {
allowed_iam_policies = join(", ", formatlist("\"%s\"", distinct(concat(local.additional_iam_policy_arns, local.default_allowed_iam_policies))))
arn_like_vpcs = formatlist("\"arn:%s:ec2:%s:%s:vpc/%s\"", local.aws_partition, var.region, local.account_id, var.vpc_allowed_ids)
arn_like_vpcs_str = format("[%s]", join(",", local.arn_like_vpcs))
assume_conditions = concat(local.external_id, local.source_identity, local.principal_check, local.vendor_federation)
support_assume_conditions = concat(local.external_id, local.source_identity)
assume_conditions = length(var.external_ids) != 0 ? concat(local.external_ids, local.source_identity, local.principal_check, local.vendor_federation) : concat(local.external_id, local.source_identity, local.principal_check, local.vendor_federation)
support_assume_conditions = length(var.external_ids) != 0 ? concat(local.external_ids, local.source_identity) : concat(local.external_id, local.source_identity)
aws_partition = data.aws_partition.current.partition
build_r53_arns = [for i, v in var.hosted_zone_allowed_ids : format("\"arn:%s:route53:::hostedzone/%s\"", local.aws_partition, v)]
ebs_kms_key_arn = length(var.ebs_kms_key_arns) > 0 ? var.ebs_kms_key_arns : [data.aws_kms_key.ebs_default.arn]
external_id = (var.external_id != "" ? [{ test : "StringEquals", variable : "sts:ExternalId", values : [var.external_id] }] : [])
external_ids = (length(var.external_ids) != 0 ? [{ test : "ForAllValues:StringEquals", variable : "sts:ExternalId", values : var.external_ids }] : [])
kms_key_arns = join(", ", formatlist("\"%s\"", distinct(concat(local.ebs_kms_key_arn, local.s3_kms_key_arn))))
r53_zone_arns = format("[%s]", join(",", local.build_r53_arns))
s3_kms_key_arn = length(var.s3_kms_key_arns) > 0 ? var.s3_kms_key_arns : [data.aws_kms_key.s3_default.arn]
Expand Down
7 changes: 7 additions & 0 deletions modules/aws/vendor-access/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,17 @@ variable "eks_cluster_pattern" {
}

variable "external_id" {
default = ""
description = "A external ID that correspond to your Organization within StreamNative Cloud, used for all STS assume role calls to the IAM roles created by the module. This will be the organization ID in the StreamNative console, e.g. \"o-xhopj\"."
type = string
}

variable "external_ids" {
default = []
description = "A list of external IDs that correspond to your Organization within StreamNative Cloud, used for all STS assume role calls to the IAM roles created by the module. This will be the organization ID in the StreamNative console, e.g. \"o-xhopj\"."
type = list(string)
}

variable "hosted_zone_allowed_ids" {
default = ["*"]
description = "Allows for further scoping down policy for allowed hosted zones. The IDs provided are constructed into ARNs"
Expand Down

0 comments on commit 3990b48

Please sign in to comment.