Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support permission init for control plane management volume #104

Merged
merged 33 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9ffca38
Support permission init
tuteng Dec 23, 2024
41e6788
Support s3 bucket access
tuteng Dec 23, 2024
a2b4989
Fixed example
tuteng Dec 23, 2024
a5929c5
Fixed volume module
tuteng Dec 24, 2024
559eea4
Fixed oidc provider
tuteng Dec 25, 2024
f4dbc20
Format code
tuteng Dec 25, 2024
7d46c0d
Fixed test
tuteng Dec 25, 2024
1778f65
Fixed comment
tuteng Dec 30, 2024
737a5d5
Merge branch 'feature/support-init-sn-volume-access-bak' into feature…
tuteng Dec 30, 2024
56ab268
Fixed providers
tuteng Dec 30, 2024
be99962
Removed no used module
tuteng Dec 30, 2024
9c93682
Fixed volume access
tuteng Dec 30, 2024
144090e
Fixed module
tuteng Dec 30, 2024
3450f86
Update example
tuteng Dec 30, 2024
548adf1
Removed no used file
tuteng Dec 30, 2024
6dac346
Fixed comment
tuteng Dec 31, 2024
c26dca9
Fixed comment
tuteng Dec 31, 2024
9429ef5
Fixed check
tuteng Dec 31, 2024
f05e13a
Fixed comment
tuteng Jan 2, 2025
1169a4e
Add new field
tuteng Jan 2, 2025
53159bc
Fixed comment
tuteng Jan 2, 2025
89841d6
Revert config
tuteng Jan 2, 2025
7e1708a
Fixed condition check
tuteng Jan 2, 2025
b97de86
Fixed comment
tuteng Jan 3, 2025
ab5c8a4
Fixed comment
tuteng Jan 3, 2025
a59d6e3
Fixed main file
tuteng Jan 3, 2025
c849dc1
Fixed assume conditions
tuteng Jan 3, 2025
a9e1dab
Fixed comment
tuteng Jan 3, 2025
58db995
Fixed comment
tuteng Jan 7, 2025
4fa0eb4
Fixed comment
tuteng Jan 7, 2025
4dfb5a6
Fixed cmment
tuteng Jan 8, 2025
a4f1413
Format code
tuteng Jan 8, 2025
0000db7
Add distinc func
tuteng Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions examples/aws-sn-volume/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
provider "aws" {
region = "us-west-2"
}

module "sn_managed_cloud" {
source = "github.com/streamnative/terraform-managed-cloud//modules/aws/sn-volume-access"

external_id = "max"
bucket = "test-ursa-storage"
path = "ursa"

oidc_providers = []

streamnative_vendor_access_role_arns = []
}
28 changes: 28 additions & 0 deletions modules/aws/sn-volume-access/files/sn_volume_s3_bucket.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
tuteng marked this conversation as resolved.
Show resolved Hide resolved
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
tuteng marked this conversation as resolved.
Show resolved Hide resolved
],
"Resource": [
"arn:aws:s3:::${bucket}",
"arn:aws:s3:::${bucket}/${path}"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutLifecycleConfiguration",
"s3:GetLifecycleConfiguration"
],
"Resource": [
"arn:aws:s3:::${bucket}/${path}"
]
}
]
}
112 changes: 112 additions & 0 deletions modules/aws/sn-volume-access/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
data "aws_caller_identity" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
external_id = (var.external_id != "" ? [{ test : "StringEquals", variable : "sts:ExternalId", values : [var.external_id] }] : [])
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)
source_identity = (length(var.source_identities) > 0 ? [{ test : var.source_identity_test, variable : "sts:SourceIdentity", values : var.source_identities }] : [])
oidc_providers = distinct(concat(var.oidc_providers, local.default_oidc_providers))
principal_check = (length(var.streamnative_principal_ids) > 0 ? [{ test : "StringLike", variable : "aws:PrincipalArn", values : var.streamnative_principal_ids }] : [])
tag_set = merge({ Vendor = "StreamNative", Module = "StreamNative Volume", SNVersion = var.sn_policy_version }, var.tags)
vendor_federation = (var.enforce_vendor_federation ? [{ test : "StringLike", variable : "aws:FederatedProvider", values : ["accounts.google.com"] }] : [])
# Add streamnative default eks oidc provider
default_oidc_providers = compact([

])
conditions = [
for value in local.oidc_providers :
[
{
provider : "${value}",
test : "StringEquals",
variable : "${value}:aud",
values : ["sts.amazonaws.com"]
},
{
provider : "${value}",
test : "StringEquals",
variable : "${value}:sub",
values : [format("system:serviceaccount:%s:*", var.external_id)]
}
]
]
}

resource "aws_iam_openid_connect_provider" "streamnative_oidc_providers" {
count = length(local.oidc_providers)
url = "https://${var.oidc_providers[count.index]}"
client_id_list = ["sts.amazonaws.com"]
tags = local.tag_set
}

data "aws_iam_policy_document" "streamnative_management_access" {
statement {
sid = "AllowStreamNativeControlPlaneAccess"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = var.streamnative_vendor_access_role_arns
}
dynamic "condition" {
for_each = local.assume_conditions
content {
test = condition.value["test"]
values = condition.value["values"]
variable = condition.value["variable"]
}
}
}

dynamic "statement" {
for_each = local.conditions
content {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]

principals {
type = "Federated"
identifiers = [for provider in local.oidc_providers : "arn:aws:iam::${local.account_id}:oidc-provider/${provider}" if "${provider}" == statement.value[0].provider]
}

dynamic "condition" {
for_each = toset(statement.value)
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_policy" "access_bucket_role" {
name = "sn-${var.external_id}-${var.bucket}-${var.path}"
description = "This policy sets the limits for the access s3 bucket for StreamNative's vendor access."
path = "/StreamNative/"
policy = templatefile("${path.module}/files/sn_volume_s3_bucket.json.tpl",
{
bucket = var.bucket
path = var.path
})
tags = local.tag_set
}

resource "aws_iam_role" "access_bucket_role" {
name = "sn-${var.external_id}-${var.bucket}-${var.path}"
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
}

resource "aws_iam_role_policy_attachment" "access_bucket_role" {
policy_arn = aws_iam_policy.access_bucket_role.arn
role = aws_iam_role.access_bucket_role.name
}
75 changes: 75 additions & 0 deletions modules/aws/sn-volume-access/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
variable "sn_policy_version" {
description = "The value of SNVersion tag"
default = "3.16.1" # {{ x-release-please-version }}
type = string
}

variable "region" {
default = "*"
description = "The AWS region where your instance of StreamNative Cloud is deployed. Defaults to all regions \"*\""
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 "additional_federated_identifiers" {
default = []
description = "This federated identified list for access customer s3 bucket on data plane."
type = list(string)
}

variable "streamnative_principal_ids" {
default = []
description = "When set, this applies an additional check for certain StreamNative principals to futher restrict access to which services / users can access an account."
type = list(string)
}

variable "source_identities" {
default = []
description = "Place an additional constraint on source identity, disabled by default and only to be used if specified by StreamNative"
type = list(any)
}

variable "source_identity_test" {
default = "ForAnyValue:StringLike"
description = "The test to use for source identity"
type = string
}

ciiiii marked this conversation as resolved.
Show resolved Hide resolved
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 "enforce_vendor_federation" {
default = false
description = "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."
type = bool
}

variable "bucket" {
description = "User bucket name"
type = string
}

variable "path" {
description = "S3 bucket path"
type = string
}

variable "oidc_providers" {
default = []
description = "Your aws eks cluster OIDC Providers"
type = list(string)
}
10 changes: 10 additions & 0 deletions modules/aws/sn-volume-access/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.30"
}
}
}
Loading