From 54cfb6f0c0a7a2d325691c24a3e402b6c46950e3 Mon Sep 17 00:00:00 2001 From: Guangning E Date: Wed, 8 Jan 2025 21:15:41 +0800 Subject: [PATCH] feat: Support permission init for control plane management volume (#104) --- examples/volume-access/main.tf | 11 ++++ modules/aws/volume-access/main.tf | 79 ++++++++++++++++++++++++++ modules/aws/volume-access/variables.tf | 40 +++++++++++++ modules/aws/volume-access/versions.tf | 10 ++++ 4 files changed, 140 insertions(+) create mode 100644 examples/volume-access/main.tf create mode 100644 modules/aws/volume-access/main.tf create mode 100644 modules/aws/volume-access/variables.tf create mode 100644 modules/aws/volume-access/versions.tf diff --git a/examples/volume-access/main.tf b/examples/volume-access/main.tf new file mode 100644 index 0000000..18fd98c --- /dev/null +++ b/examples/volume-access/main.tf @@ -0,0 +1,11 @@ +module "sn_managed_cloud" { + source = "../../modules/aws/volume-access" + + external_id = "" + role = "" + buckets = [] + + account_ids = [] + + streamnative_vendor_access_role_arns = [] +} \ No newline at end of file diff --git a/modules/aws/volume-access/main.tf b/modules/aws/volume-access/main.tf new file mode 100644 index 0000000..17785d8 --- /dev/null +++ b/modules/aws/volume-access/main.tf @@ -0,0 +1,79 @@ +data "aws_caller_identity" "current" {} +locals { + external_id = (var.external_id != "" ? [{ test : "StringEquals", variable : "sts:ExternalId", values : [var.external_id] }] : []) + account_ids = distinct(concat(var.account_ids, local.default_account_ids)) + identifiers_list = [for account_id in local.account_ids : "arn:aws:iam::${account_id}:root"] + bucket_list = distinct([for item in var.buckets : "arn:aws:s3:::${split("/", item)[0]}"]) + bucket_path_list = distinct([for item in var.buckets : "arn:aws:s3:::${item}"]) + tag_set = merge({ Vendor = "StreamNative", Module = "StreamNative Volume", SNVersion = var.sn_policy_version }, var.tags) + default_account_ids = compact([ + # will add it in the next pr + ]) +} + +data "aws_iam_policy_document" "streamnative_management_access" { + statement { + sid = "AllowStreamNativeControlPlaneAccess" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "AWS" + identifiers = distinct(concat(var.streamnative_vendor_access_role_arns, local.identifiers_list)) + } + dynamic "condition" { + for_each = local.external_id + content { + test = condition.value["test"] + values = condition.value["values"] + variable = condition.value["variable"] + } + } + } +} + +###### +#-- Create the IAM role for the the StreamNative Cloud data plane access to s3 bucket +###### +resource "aws_iam_role_policy" "access_bucket_role" { + name = var.role + role = aws_iam_role.access_bucket_role.id + policy = jsonencode({ + "Version" : "2012-10-17", + "Statement" : [ + { + "Effect" : "Allow", + "Action" : [ + "s3:ListBucket" + ], + "Resource" : local.bucket_list + }, + { + "Effect" : "Allow", + "Action" : [ + "s3:PutObject", + "s3:GetObject", + "s3:DeleteObject" + ], + "Resource" : [for item in local.bucket_path_list : "${item}/*"] + }, + { + "Effect" : "Allow", + "Action" : [ + "s3:PutLifecycleConfiguration", + "s3:GetLifecycleConfiguration" + ], + "Resource" : local.bucket_path_list + } + ] + }) +} + +resource "aws_iam_role" "access_bucket_role" { + name = var.role + description = "This role is used by StreamNative for the access s3 bucket." + assume_role_policy = data.aws_iam_policy_document.streamnative_management_access.json + path = "/StreamNative/" + tags = local.tag_set + max_session_duration = 43200 +} \ No newline at end of file diff --git a/modules/aws/volume-access/variables.tf b/modules/aws/volume-access/variables.tf new file mode 100644 index 0000000..3773061 --- /dev/null +++ b/modules/aws/volume-access/variables.tf @@ -0,0 +1,40 @@ +variable "sn_policy_version" { + description = "The value of SNVersion tag" + default = "3.16.1" # {{ x-release-please-version }} + type = string +} + +variable "streamnative_vendor_access_role_arns" { + default = ["arn:aws:iam::311022431024:role/cloud-manager"] + description = "This role for access customer s3 bucket on control plane." + type = list(string) +} + +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 "tags" { + default = {} + description = "Extra tags to apply to the resources created by this module." + type = map(string) +} + +variable "buckets" { + default = [] + description = "User bucket and path name" + type = list(string) +} + +variable "role" { + description = "Your aws iam role for access s3 bucket" + type = string +} + +variable "account_ids" { + default = [] + description = "Your account id" + type = list(string) +} \ No newline at end of file diff --git a/modules/aws/volume-access/versions.tf b/modules/aws/volume-access/versions.tf new file mode 100644 index 0000000..720774c --- /dev/null +++ b/modules/aws/volume-access/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.30" + } + } +} \ No newline at end of file