Skip to content

Commit

Permalink
Support permission init
Browse files Browse the repository at this point in the history
  • Loading branch information
tuteng committed Dec 23, 2024
1 parent decac0c commit 9ffca38
Show file tree
Hide file tree
Showing 6 changed files with 379 additions and 0 deletions.
9 changes: 9 additions & 0 deletions examples/aws-sn-volume/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
provider "aws" {
region = "us-west-2"
}

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

external_id = "o-rlgba"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowedIAMReadActions",
"Effect": "Allow",
"Action": [
"iam:GetPolicy*",
"iam:GetRole*"
],
"Resource": [
"arn:${partition}:iam::${account_id}:role/StreamNative/*",
"arn:${partition}:iam::${account_id}:policy/StreamNative/*"
]
},
{
"Sid": "IamRequireRequestTag",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:TagPolicy",
"iam:TagRole"
],
"Resource": [
"arn:${partition}:iam::${account_id}:role/StreamNative/*",
"arn:${partition}:iam::${account_id}:policy/StreamNative/*"
],
"Condition": {
"StringEqualsIgnoreCase": {
"aws:RequestTag/Vendor": "StreamNative"
}
}
},
{
"Sid": "IamAttach",
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy"
],
"Resource": "arn:${partition}:iam::${account_id}:role/StreamNative/*"
},
{
"Sid": "s3o",
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:ListBucket"
],
"Resource": "arn:${partition}:iam::${account_id}:role/StreamNative/*"
},
{
"Sid": "IamRequireResourceTag",
"Effect": "Allow",
"Action": [
"iam:DeleteRole",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:DeleteRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:SetDefaultPolicyVersion",
"iam:UpdateAssumeRolePolicy",
"iam:UpdateRole",
"iam:UpdateRoleDescription"
],
"Resource": [
"arn:${partition}:iam::${account_id}:role/StreamNative/*",
"arn:${partition}:iam::${account_id}:policy/StreamNative/*"
],
"Condition": {
"StringEqualsIgnoreCase": {
"aws:ResourceTag/Vendor": "StreamNative"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowedServices",
"Effect": "Allow",
"Action": [
"iam:Get*",
"iam:List*",
"s3:Get*"
],
"Resource": [
"arn:${partition}:iam::${account_id}:role/StreamNative/*"
]
},
{
"Sid": "IamRestrictions",
"Effect": "Allow",
"Action": [
"iam:AddRoleToInstanceProfile",
"iam:CreateOpenIDConnectProvider",
"iam:CreateServiceLinkedRole",
"iam:CreatePolicy*",
"iam:DeleteInstanceProfile",
"iam:DeleteOpenIDConnectProvider",
"iam:DeletePolicy*",
"iam:DeleteRole",
"iam:DeleteServiceLinkedRole",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:DeleteRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:RemoveRoleFromInstanceProfile",
"iam:SetDefaultPolicyVersion",
"iam:Tag*",
"iam:Untag*",
"iam:UpdateAssumeRolePolicy",
"iam:UpdateOpenIDConnectProviderThumbprint",
"iam:UpdateRole",
"iam:UpdateRoleDescription"
],
"Resource": [
"arn:${partition}:iam::${account_id}:role/StreamNative/*",
"arn:${partition}:iam::${account_id}:policy/StreamNative/*"
]
},
{
"Sid": "AllowedIAMManagedPolicies",
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy"
],
"Resource": "arn:${partition}:iam::${account_id}:role/StreamNative/*",
"Condition": {
"ForAnyValue:ArnLike": {
"iam:PolicyARN": [ ${allowed_iam_policies} ]
}
}
},
{
"Sid": "RequirePermissionBoundaryForIamRoles",
"Effect": "Allow",
"Action": [
"iam:CreateRole"
],
"Resource": "arn:${partition}:iam::${account_id}:role/StreamNative/*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:${partition}:iam::${account_id}:policy/StreamNative/StreamNativeCloudVolumePermissionBoundary"
}
}
},
{
"Sid": "RestrictChangesToVendorAccess",
"Effect": "Deny",
"Action": [
"iam:Create*",
"iam:Delete*",
"iam:Put*",
"iam:Tag*",
"iam:Untag*",
"iam:Update*",
"iam:Set*"
],
"Resource": [
"arn:${partition}:iam::${account_id}:policy/StreamNative/StreamNativeCloudVolumeManagementRole"
]
}
]
}
111 changes: 111 additions & 0 deletions modules/aws/sn-volume-access/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
data "aws_caller_identity" "current" {}

data "aws_partition" "current" {}

locals {
account_id = data.aws_caller_identity.current.account_id
additional_iam_policy_arns = distinct(compact(var.additional_iam_policy_arns))
allowed_iam_policies = join(", ", formatlist("\"%s\"", distinct(concat(local.additional_iam_policy_arns, local.default_allowed_iam_policies))))
aws_partition = data.aws_partition.current.partition
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)
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 }] : [])
principal_check = (length(var.streamnative_principal_ids) > 0 ? [{ test : "StringLike", variable : "aws:PrincipalArn", values : var.streamnative_principal_ids }] : [])
vendor_federation = (var.enforce_vendor_federation ? [{ test : "StringLike", variable : "aws:FederatedProvider", values : ["accounts.google.com"] }] : [])
source_identity = (length(var.source_identities) > 0 ? [{ test : var.source_identity_test, variable : "sts:SourceIdentity", values : var.source_identities }] : [])
tag_set = merge({ Vendor = "StreamNative", Module = "StreamNative Volume", SNVersion = var.sn_policy_version }, var.tags)
default_allowed_iam_policies = compact([
"arn:${local.aws_partition}:iam::${local.account_id}:policy/StreamNative/*"
])
}

data "aws_iam_policy_document" "streamnative_management_access" {
statement {
sid = "AllowStreamNativeVendorAccess"
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"]
}
}
}

statement {
sid = "AllowStreamNativeControlPlaneAccess"
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]

principals {
type = "Federated"
identifiers = [
"accounts.google.com"
]
}
condition {
test = "StringEquals"
values = length(var.streamnative_google_account_ids) > 0 ? var.streamnative_google_account_ids : [var.streamnative_google_account_id]
variable = "accounts.google.com:aud"
}
}
}

######
#-- Create the IAM Permission Boundary used by all StreamNative
#-- IAM Resources. This restricts what type of access we have
#-- within your AWS Account and is applied to all our IAM Roles
######
resource "aws_iam_policy" "permission_boundary" {
name = "StreamNativeCloudVolumePermissionBoundary${var.test_suffix}"
description = "This policy sets the permission boundary for StreamNative's vendor access. It defines the limits of what StreamNative can do within this AWS account."
path = "/StreamNative/"
policy = templatefile("${path.module}/files/sn_volume_permission_boundary_iam_policy.json.tpl",
{
account_id = local.account_id
allowed_iam_policies = local.allowed_iam_policies
partition = local.aws_partition
region = var.region
})
tags = local.tag_set
}

######
#-- Create the IAM role for the management of the StreamNative Cloud Volume
#-- This role is used by StreamNative for volume management and troubleshooting
#-- of the managed deployment.
######
resource "aws_iam_policy" "management_role" {
name = "StreamNativeCloudVolumeManagementPolicy${var.test_suffix}"
description = "This policy sets the limits for the management role needed for StreamNative's vendor volume access."
path = "/StreamNative/"
policy = templatefile("${path.module}/files/sn_volume_management_role_iam_policy.json.tpl",
{
account_id = data.aws_caller_identity.current.account_id
partition = local.aws_partition
region = var.region
})
tags = local.tag_set
}

resource "aws_iam_role" "management_role" {
name = "StreamNativeCloudVolumeManagementRole${var.test_suffix}"
description = "This role is used by StreamNative for the day to day management of the StreamNative Cloud Volume deployment."
assume_role_policy = data.aws_iam_policy_document.streamnative_management_access.json
path = "/StreamNative/"
permissions_boundary = aws_iam_policy.permission_boundary.arn
tags = local.tag_set
max_session_duration = 43200
}

resource "aws_iam_role_policy_attachment" "management_role" {
policy_arn = aws_iam_policy.management_role.arn
role = aws_iam_role.management_role.name
}
83 changes: 83 additions & 0 deletions modules/aws/sn-volume-access/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
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_google_account_id" {
default = "108050666045451143798"
description = "(Deprecated, use streamnative_google_account_ids instead) The Google Cloud service account ID used by StreamNative for Control Plane operations"
type = string
}

variable "streamnative_google_account_ids" {
default = ["108050666045451143798"]
description = "The Google Cloud service account IDs used by StreamNative for Control Plane operations"
type = list(string)
}

variable "streamnative_vendor_access_role_arns" {
default = ["arn:aws:iam::311022431024:role/cloud-manager"]
description = "A list ARNs provided by StreamNative that enable us to work with the Vendor Access Roles created by this module (StreamNativeCloudBootstrapRole, StreamNativeCloudManagementRole). This is how StreamNative is granted access into your AWS account, and should typically be the default value unless directed otherwise. This arns are used *only* for automations."
type = list(string)
}

variable "additional_iam_policy_arns" {
default = []
description = "Provide a list of additional IAM policy arns allowed for use with iam:AttachRolePolicy, defined in the StreamNativePermissionBoundary."
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
}

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 "tags" {
default = {}
description = "Extra tags to apply to the resources created by this module."
type = map(string)
}

variable "test_suffix" {
default = ""
description = "Used in testing to apply us to apply multiple versions of the role"
type = 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
}
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"
}
}
}

0 comments on commit 9ffca38

Please sign in to comment.