Skip to content

Commit

Permalink
[iam] introduce iam_compartmen_id which define the top parent compart…
Browse files Browse the repository at this point in the history
…ment for IAM resources when not at tenancy level

  - + describe usage of a Custom Identity Domain within an OCI subcompartment

Signed-off-by: Thomas Pham <[email protected]>
  • Loading branch information
thpham committed Dec 8, 2023
1 parent 4c272ec commit 27b7726
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 28 deletions.
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [Identity](./guide/identity.md)
- [Policies](./guide/identity_policies.md)
- [Tags](./guide/identity_tags.md)
- [Identity Domain](./guide/identity_domain.md)
- [Network](./guide/network.md)
- [Subnets](./guide/network_subnets.md)
- [Network Security Groups](./guide/network_nsgs.md)
Expand Down
4 changes: 3 additions & 1 deletion docs/src/guide/identity.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Identity

Optional creation of Identity Dynamic Groups, Policies, and Tags.
## IAM without Identity Domains

Optional creation of Identity [Dynamic Groups](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm), [Policies](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingpolicies.htm), and Tags.
16 changes: 16 additions & 0 deletions docs/src/guide/identity_domain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# IAM with Identity Domains

Creation of Identity [Dynamic Groups](https://docs.oracle.com/en-us/iaas/Content/Identity/dynamicgroups/managingdynamicgroups.htm), [Policies](https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingpolicies.htm), and Tags.


## Context

While you might not have the necessary policy permissions to provision OKE clusters directly at Tenancy level (ROOT compartment) and you have full control only under a sub-compartment, the following parameters will allow you to reference an existing and custom `identity domain` at this sub-compartment level. The `Dynamic Groups` will be then created in this Identity Domain while the policies will be created at the sub-compartment level and their statements using the `dynamic group` in your `identity domain`

Moreover, You can use this Identity Domain, to create service account users for your Kubernetes/OKE controllers or operators.

## Usage

```javascript
{{#include ../../../examples/iam/vars-subcompartment-iam-identitydomain.auto.tfvars:4:}}
```
3 changes: 2 additions & 1 deletion module-iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ module "iam" {
source = "./modules/iam"
compartment_id = local.compartment_id
state_id = local.state_id
tenancy_id = local.tenancy_id
tenancy_id = local.iam_compartment_id
identity_domain_name = local.identity_domain_name
cluster_id = local.cluster_id
create_iam_resources = var.create_iam_resources
create_iam_autoscaler_policy = local.create_iam_autoscaler_policy
Expand Down
26 changes: 26 additions & 0 deletions modules/iam/data-common.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2022, 2023 Oracle Corporation and/or its affiliates.
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl

locals {
identity_domain_name = coalesce(var.identity_domain_name, "Default" )
isDefaultIdentityDomain = local.identity_domain_name == "Default" ? true : false
}

data "oci_identity_domains" "domains" {
count = local.isDefaultIdentityDomain ? 0 : 1

#Required
compartment_id = var.tenancy_id # dynamic groups exist in the parent compartment.

#Optional
display_name = var.identity_domain_name
#home_region_url = var.domain_home_region_url ## TODO: provide the home region
#is_hidden_on_login = var.domain_is_hidden_on_login
#license_type = var.domain_license_type
#name = var.domain_name
#state = var.domain_state
#type = var.domain_type
#url = var.domain_url

provider = oci.home
}
35 changes: 25 additions & 10 deletions modules/iam/group-autoscaling.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,26 @@ locals {
])) : local.autoscaler_compartment_rule

autoscaler_templates = [
"Allow dynamic-group %v to manage cluster-node-pools in compartment id %v",
"Allow dynamic-group %v to manage compute-management-family in compartment id %v",
"Allow dynamic-group %v to manage instance-family in compartment id %v",
"Allow dynamic-group %v to manage volume-family in compartment id %v",
"Allow dynamic-group %v to use subnets in compartment id %v",
"Allow dynamic-group %v to read virtual-network-family in compartment id %v",
"Allow dynamic-group %v to use vnics in compartment id %v",
"Allow dynamic-group %v to inspect compartments in compartment id %v",
"Allow dynamic-group '%v'/'%v' to manage cluster-node-pools in compartment id %v",
"Allow dynamic-group '%v'/'%v' to manage compute-management-family in compartment id %v",
"Allow dynamic-group '%v'/'%v' to manage instance-family in compartment id %v",
"Allow dynamic-group '%v'/'%v' to manage volume-family in compartment id %v",
"Allow dynamic-group '%v'/'%v' to use subnets in compartment id %v",
"Allow dynamic-group '%v'/'%v' to read virtual-network-family in compartment id %v",
"Allow dynamic-group '%v'/'%v' to use vnics in compartment id %v",
"Allow dynamic-group '%v'/'%v' to inspect compartments in compartment id %v",
]

autoscaler_policy_statements = var.create_iam_autoscaler_policy ? tolist([
for statement in local.autoscaler_templates : formatlist(statement,
local.autoscaler_group_name, local.worker_compartments,
local.identity_domain_name, local.autoscaler_group_name, local.worker_compartments,
)
]) : []
}

resource "oci_identity_dynamic_group" "autoscaling" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_autoscaler_policy ? 1 : 0
count = var.create_iam_resources && var.create_iam_autoscaler_policy && local.isDefaultIdentityDomain ? 1 : 0
compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)
description = format("Dynamic group of cluster autoscaler-capable worker nodes for OKE Terraform state %v", var.state_id)
matching_rule = local.autoscaler_group_rules
Expand All @@ -45,3 +45,18 @@ resource "oci_identity_dynamic_group" "autoscaling" {
ignore_changes = [defined_tags, freeform_tags]
}
}

resource "oci_identity_domains_dynamic_resource_group" "autoscaling" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_autoscaler_policy && !local.isDefaultIdentityDomain ? 1 : 0
#Optional
description = format("Dynamic group of cluster autoscaler-capable worker nodes for OKE Terraform state %v", var.state_id)
#Required
matching_rule = local.autoscaler_group_rules
display_name = local.autoscaler_group_name
idcs_endpoint = data.oci_identity_domains.domains[0].domains[0]["url"]
schemas = [
"urn:ietf:params:scim:schemas:oracle:idcs:DynamicResourceGroup",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:OCITags"
]
}
21 changes: 18 additions & 3 deletions modules/iam/group-cluster.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ locals {

# Cluster secrets encryption using OCI Key Management System (KMS)
cluster_policy_statements = coalesce(var.cluster_kms_key_id, "none") != "none" ? tolist([format(
"Allow dynamic-group %v to use keys in compartment id %v where target.key.id = '%v'",
local.cluster_group_name, var.compartment_id, var.cluster_kms_key_id,
"Allow dynamic-group '%v'/'%v' to use keys in compartment id %v where target.key.id = '%v'",
local.identity_domain_name, local.cluster_group_name, var.compartment_id, var.cluster_kms_key_id,
)]) : []
}

resource "oci_identity_dynamic_group" "cluster" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_kms_policy ? 1 : 0
count = var.create_iam_resources && var.create_iam_kms_policy && local.isDefaultIdentityDomain ? 1 : 0
compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)
description = format("Dynamic group with cluster for OKE Terraform state %v", var.state_id)
matching_rule = local.cluster_rule
Expand All @@ -30,3 +30,18 @@ resource "oci_identity_dynamic_group" "cluster" {
ignore_changes = [defined_tags, freeform_tags]
}
}

resource "oci_identity_domains_dynamic_resource_group" "cluster" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_kms_policy && !local.isDefaultIdentityDomain ? 1 : 0
#Optional
description = format("Dynamic group with cluster for OKE Terraform state %v", var.state_id)
#Required
matching_rule = local.cluster_rule
display_name = local.cluster_group_name
idcs_endpoint = data.oci_identity_domains.domains[0].domains[0]["url"]
schemas = [
"urn:ietf:params:scim:schemas:oracle:idcs:DynamicResourceGroup",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:OCITags"
]
}
21 changes: 18 additions & 3 deletions modules/iam/group-operator.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ locals {
])) : "ALL {instance.compartment.id = '${var.compartment_id}'}"

cluster_manage_statement = format(
"Allow dynamic-group %v to MANAGE clusters in compartment id %v",
local.operator_group_name, var.compartment_id,
"Allow dynamic-group '%v'/'%v' to MANAGE clusters in compartment id %v",
local.identity_domain_name ,local.operator_group_name, var.compartment_id,
)

# TODO support keys defined at worker group level
Expand All @@ -33,7 +33,7 @@ locals {

resource "oci_identity_dynamic_group" "operator" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_operator_policy ? 1 : 0
count = var.create_iam_resources && var.create_iam_operator_policy && local.isDefaultIdentityDomain ? 1 : 0
compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)
description = format("Dynamic group of operator instance(s) for OKE Terraform state %v", var.state_id)
matching_rule = local.operator_group_rules
Expand All @@ -44,3 +44,18 @@ resource "oci_identity_dynamic_group" "operator" {
ignore_changes = [defined_tags, freeform_tags]
}
}

resource "oci_identity_domains_dynamic_resource_group" "operator" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_operator_policy && !local.isDefaultIdentityDomain ? 1 : 0
#Optional
description = format("Dynamic group of operator instance(s) for OKE Terraform state %v", var.state_id)
#Required
matching_rule = local.operator_group_rules
display_name = local.operator_group_name
idcs_endpoint = data.oci_identity_domains.domains[0].domains[0]["url"]
schemas = [
"urn:ietf:params:scim:schemas:oracle:idcs:DynamicResourceGroup",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:OCITags"
]
}
23 changes: 19 additions & 4 deletions modules/iam/group-workers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ locals {
])))

cluster_join_statements = formatlist(
"Allow dynamic-group %v to {CLUSTER_JOIN} in compartment id %v where %v",
local.worker_group_name, local.worker_compartments, local.cluster_join_where_clause
"Allow dynamic-group '%v'/'%v' to {CLUSTER_JOIN} in compartment id %v where %v",
local.identity_domain_name, local.worker_group_name, local.worker_compartments, local.cluster_join_where_clause
)

# TODO support keys defined at worker group level
worker_kms_volume_templates = tolist([
"Allow service oke to USE key-delegates in compartment id %v where target.key.id = '%v'",
"Allow service blockstorage to USE keys in compartment id %v where target.key.id = '%v'",
"Allow dynamic-group ${local.worker_group_name} to USE key-delegates in compartment id %v where target.key.id = '%v'"
"Allow dynamic-group '${local.identity_domain_name}'/'${local.worker_group_name}' to USE key-delegates in compartment id %v where target.key.id = '%v'"
])

# Block volume encryption using OCI Key Management System (KMS)
Expand All @@ -43,7 +43,7 @@ locals {

resource "oci_identity_dynamic_group" "workers" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_worker_policy ? 1 : 0
count = var.create_iam_resources && var.create_iam_worker_policy && local.isDefaultIdentityDomain ? 1 : 0
compartment_id = var.tenancy_id # dynamic groups exist in root compartment (tenancy)
description = format("Dynamic group of self-managed worker nodes for OKE Terraform state %v", var.state_id)
matching_rule = local.worker_group_rules
Expand All @@ -54,3 +54,18 @@ resource "oci_identity_dynamic_group" "workers" {
ignore_changes = [defined_tags, freeform_tags]
}
}

resource "oci_identity_domains_dynamic_resource_group" "workers" {
provider = oci.home
count = var.create_iam_resources && var.create_iam_worker_policy && !local.isDefaultIdentityDomain ? 1 : 0
#Optional
description = format("Dynamic group of self-managed worker nodes for OKE Terraform state %v", var.state_id)
#Required
matching_rule = local.worker_group_rules
display_name = local.worker_group_name
idcs_endpoint = data.oci_identity_domains.domains[0].domains[0]["url"]
schemas = [
"urn:ietf:params:scim:schemas:oracle:idcs:DynamicResourceGroup",
"urn:ietf:params:scim:schemas:oracle:idcs:extension:OCITags"
]
}
17 changes: 11 additions & 6 deletions modules/iam/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@

output "dynamic_group_ids" {
description = "Cluster IAM dynamic group IDs"
value = local.has_policy_statements ? compact([
one(oci_identity_dynamic_group.cluster[*].id),
one(oci_identity_dynamic_group.workers[*].id),
one(oci_identity_dynamic_group.autoscaling[*].id),
one(oci_identity_dynamic_group.operator[*].id),
]) : null
value = local.has_policy_statements && local.isDefaultIdentityDomain ? compact([
one(oci_identity_dynamic_group.cluster[*].id),
one(oci_identity_dynamic_group.workers[*].id),
one(oci_identity_dynamic_group.autoscaling[*].id),
one(oci_identity_dynamic_group.operator[*].id),
]) : local.has_policy_statements && !local.isDefaultIdentityDomain ? compact([
one(oci_identity_domains_dynamic_resource_group.cluster[*].id),
one(oci_identity_domains_dynamic_resource_group.workers[*].id),
one(oci_identity_domains_dynamic_resource_group.autoscaling[*].id),
one(oci_identity_domains_dynamic_resource_group.operator[*].id),
]) : null
}

output "policy_statements" {
Expand Down
1 change: 1 addition & 0 deletions modules/iam/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ variable "compartment_id" { type = string }
variable "state_id" { type = string }
variable "tenancy_id" { type = string }
variable "worker_compartments" { type = list(string) }
variable "identity_domain_name" { type = string }

# Tags
variable "create_iam_defined_tags" { type = bool }
Expand Down
14 changes: 14 additions & 0 deletions variables-iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

locals {
tenancy_id = coalesce(var.tenancy_id, var.tenancy_ocid, "unknown")
iam_compartment_id = coalesce(var.iam_compartment_id, local.tenancy_id)
identity_domain_name = coalesce(var.identity_domain_name, "Default")
compartment_id = coalesce(var.compartment_id, var.compartment_ocid, var.tenancy_id)
worker_compartment_id = coalesce(var.worker_compartment_id, var.compartment_id)
user_id = var.user_id != "" ? var.user_id : var.current_user_ocid
Expand Down Expand Up @@ -50,6 +52,18 @@ variable "tenancy_ocid" {
type = string
}

variable "iam_compartment_id" {
default = null
description = "The comparment id of the parent comparment in which to create the IAM resources."
type = string
}

variable "identity_domain_name" {
default = null
description = "The Identity domain name to use. If not defined, it will use the tenancy default"
type = string
}

# Overrides Resource Manager
variable "user_id" {
default = null
Expand Down

0 comments on commit 27b7726

Please sign in to comment.