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: Adding flexibility for RBACs definition. #21

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
243 changes: 15 additions & 228 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,247 +4,31 @@ Terraform module which creates multi-tenancy resources on Amazon EKS.

## Usage

See [`tests`](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/test) directory for working tests to reference:
See [`patterns`](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns) directory for working references.

### Cluster Admin

### Standalone - Admin Team
This example bounds `cluster-admin` Kubernetes clusterRole permission to the specified identities. The `cluster-admin` has **unrestricted** access to manage cluster resources. More information can be found in the [`patterns/cluster-admin`](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/cluster-admin) directory.

```hcl
module "admin_team" {
source = "aws-ia/eks-blueprints-teams/aws"
https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/blob/42d0c1005e14f807de12a2baf9961ab272d78264/tests/complete/main.tf#L38-L49

name = "admin-team"
### Namespaced Admin

# Enables elevated, admin privileges for this team
enable_admin = true
users = ["arn:aws:iam::111122223333:role/my-admin-role"]
cluster_arn = "arn:aws:eks:us-west-2:111122223333:cluster/my-cluster"
To define a namespaced-admin, you need to inform the existing `admin` Kubernetes role in the `aditional_role` variable, in order to bind it to the specified identities. More information can be found in the [`patterns/namespace-admin`](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/namespaced-admin) directory.

tags = {
Environment = "dev"
}
}
```
https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/blob/42d0c1005e14f807de12a2baf9961ab272d78264/tests/complete/main.tf#L50-L76

### Standalone - Developer Team
### Single Development Team

```hcl
module "development_team" {
source = "aws-ia/eks-blueprints-teams/aws"
Here you will define a team that have access only to specific Namespaces, with granulzarized permissions and access control to other resources in the cluster through Kubernetes networkPolicies, resourceQuotas, and limits. More information can be found in the [`patterns/development-team`](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/namespaced-admin) directory.

name = "development-team"

users = ["arn:aws:iam::012345678901:role/my-developer"]
cluster_arn = "arn:aws:eks:us-west-2:012345678901:cluster/my-cluster"
oidc_provider_arn = "arn:aws:iam::012345678901:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/5C54DDF35ER19312844C7333374CC09D"

# Labels applied to all Kubernetes resources
# More specific labels can be applied to individual resources under `namespaces` below
labels = {
team = "development"
}

# Annotations applied to all Kubernetes resources
# More specific labels can be applied to individual resources under `namespaces` below
annotations = {
team = "development"
}

namespaces = {
default = {
# Provides access to an existing namespace
create = false
}

development = {
labels = {
projectName = "project-awesome",
}

resource_quota = {
hard = {
"requests.cpu" = "1000m",
"requests.memory" = "4Gi",
"limits.cpu" = "2000m",
"limits.memory" = "8Gi",
"pods" = "10",
"secrets" = "10",
"services" = "10"
}
}

limit_range = {
limit = [
{
type = "Pod"
max = {
cpu = "200m"
memory = "1Gi"
}
},
{
type = "PersistentVolumeClaim"
min = {
storage = "24M"
}
},
{
type = "Container"
default = {
cpu = "50m"
memory = "24Mi"
}
}
]
}

network_policy = {
pod_selector = {
match_expressions = [{
key = "name"
operator = "In"
values = ["webfront", "api"]
}]
}

ingress = [{
ports = [
{
port = "http"
protocol = "TCP"
},
{
port = "53"
protocol = "TCP"
},
{
port = "53"
protocol = "UDP"
}
]

from = [
{
namespace_selector = {
match_labels = {
name = "default"
}
}
},
{
ip_block = {
cidr = "10.0.0.0/8"
except = [
"10.0.0.0/24",
"10.0.1.0/24",
]
}
}
]
}]

egress = [] # single empty rule to allow all egress traffic

policy_types = ["Ingress", "Egress"]
}
}
}

tags = {
Environment = "dev"
}
}
```
https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/blob/42d0c1005e14f807de12a2baf9961ab272d78264/tests/complete/main.tf#L77-L195

### Multiple Teams

You can utilize a module level `for_each` to create multiple teams with the same configuration, and even allow some of those values to be defaults that can be overridden.

```hcl
module "development_team" {
source = "aws-ia/eks-blueprints-teams/aws"

for_each = {
one = {
# Add any additional variables here and update definition below to use
users = ["arn:aws:iam::012345678901:role/developers-one"]
}
two = {
users = ["arn:aws:iam::012345678901:role/developers-two"]
}
three = {
users = ["arn:aws:iam::012345678901:role/developers-three"]
}
}

name = "${each.key}-team"

users = each.value.users
cluster_arn = "arn:aws:eks:us-west-2:012345678901:cluster/my-cluster"
oidc_provider_arn = "arn:aws:iam::012345678901:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/5C54DDF35ER19312844C7333374CC09D"

# Labels applied to all Kubernetes resources
# More specific labels can be applied to individual resources under `namespaces` below
labels = {
team = each.key
}

# Annotations applied to all Kubernetes resources
# More specific labels can be applied to individual resources under `namespaces` below
annotations = {
team = each.key
}

namespaces = {
(each.key) = {
labels = {
projectName = "project-awesome",
}

resource_quota = {
hard = {
"requests.cpu" = "1000m",
"requests.memory" = "4Gi",
"limits.cpu" = "2000m",
"limits.memory" = "8Gi",
"pods" = "10",
"secrets" = "10",
"services" = "10"
}
}

limit_range = {
limit = [
{
type = "Pod"
max = {
cpu = "200m"
memory = "1Gi"
}
},
{
type = "PersistentVolumeClaim"
min = {
storage = "24M"
}
},
{
type = "Container"
default = {
cpu = "50m"
memory = "24Mi"
}
}
]
}
}
}
You can utilize a the Terraform `for_each` Meta-Argument at the Module level to create multiple teams with the same configuration, and even allow some of those values to be defaults that can be overridden. More information can be found in the [`patterns/multiple-app-teams`](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/namespaced-admin) directory.

tags = {
Environment = "dev"
}
}
```
https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/blob/42d0c1005e14f807de12a2baf9961ab272d78264/tests/complete/main.tf#L196-L231

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
Expand Down Expand Up @@ -290,10 +74,12 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_role_ref"></a> [additional\_role\_ref](#input\_additional\_role\_ref) | Existing Role or ClusterRole to be referenced on the Kubernetes clusterRoleBinding created | `any` | `{}` | no |
| <a name="input_admin_policy_name"></a> [admin\_policy\_name](#input\_admin\_policy\_name) | Name to use on admin IAM policy created | `string` | `""` | no |
| <a name="input_annotations"></a> [annotations](#input\_annotations) | A map of Kubernetes annotations to add to all resources | `map(string)` | `{}` | no |
| <a name="input_cluster_arn"></a> [cluster\_arn](#input\_cluster\_arn) | The Amazon Resource Name (ARN) of the cluster | `string` | `""` | no |
| <a name="input_cluster_role_name"></a> [cluster\_role\_name](#input\_cluster\_role\_name) | Name to use on Kubernetes cluster role created | `string` | `""` | no |
| <a name="input_cluster_role_rule"></a> [cluster\_role\_rule](#input\_cluster\_role\_rule) | Defines the Kubernetes RBAC based `api_groups`, `resources`, and `verbs` Rules for the role created | `any` | `{}` | no |
| <a name="input_create_cluster_role"></a> [create\_cluster\_role](#input\_create\_cluster\_role) | Determines whether a Kubernetes cluster role is created | `bool` | `true` | no |
| <a name="input_create_iam_role"></a> [create\_iam\_role](#input\_create\_iam\_role) | Determines whether an IAM role is created or to use an existing IAM role | `bool` | `true` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Determines whether a Kubernetes role is created. Note: the role created is a cluster role but its bound to only namespaced role bindings | `bool` | `true` | no |
Expand All @@ -312,6 +98,7 @@ No modules.
| <a name="input_oidc_provider_arn"></a> [oidc\_provider\_arn](#input\_oidc\_provider\_arn) | ARN of the OIDC provider created by the EKS cluster | `string` | `""` | no |
| <a name="input_principal_arns"></a> [principal\_arns](#input\_principal\_arns) | A list of IAM principal arns to support passing wildcards for AWS Identity Center (SSO) roles. [Reference](https://docs.aws.amazon.com/singlesignon/latest/userguide/referencingpermissionsets.html#custom-trust-policy-example) | `list(string)` | `[]` | no |
| <a name="input_role_name"></a> [role\_name](#input\_role\_name) | Name to use on Kubernetes role created | `string` | `""` | no |
| <a name="input_role_ref"></a> [role\_ref](#input\_role\_ref) | Defines the reference for an existing Kubernetes role | `any` | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all AWS resources | `map(string)` | `{}` | no |
| <a name="input_users"></a> [users](#input\_users) | A list of IAM user and/or role ARNs that can assume the IAM role created | `list(string)` | `[]` | no |

Expand Down
21 changes: 12 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -316,25 +316,28 @@ resource "kubernetes_cluster_role_v1" "this" {
}

rule {
api_groups = [""]
resources = ["namespaces", "nodes"]
verbs = ["get", "list", "watch"]
api_groups = try(var.cluster_role_rule.api_groups, [""])
resources = try(var.cluster_role_rule.resources, ["namespaces", "nodes"])
verbs = try(var.cluster_role_rule.verbs, ["get", "list", "watch"])
}
}

################################################################################
# K8s Cluster Role Binding
################################################################################
resource "kubernetes_cluster_role_binding_v1" "this" {
count = var.create_cluster_role && !var.enable_admin ? 1 : 0
for_each = var.create_cluster_role && !var.enable_admin ? { for k, v in flatten([kubernetes_cluster_role_v1.this[0].metadata[0].name, try(var.additional_role_ref.name, "")]) : k => v if var.additional_role_ref != {} } : {}

metadata {
name = kubernetes_cluster_role_v1.this[0].metadata[0].name
name = each.value == kubernetes_cluster_role_v1.this[0].metadata[0].name ? kubernetes_cluster_role_v1.this[0].metadata[0].name : coalesce("${var.cluster_role_name}-${each.value}-additional", "${var.name}-${each.value}-additional")
annotations = var.annotations
labels = var.labels
}

role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role_v1.this[0].metadata[0].name
kind = try(var.additional_role_ref.kind, "ClusterRole")
name = each.value
}

subject {
Expand Down Expand Up @@ -364,8 +367,8 @@ resource "kubernetes_role_binding_v1" "this" {
# determined by the fact that this is a role binding (kubernetes_role_binding_v1).
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "view"
kind = try(var.role_ref.kind, "ClusterRole")
name = try(var.role_ref.name, "view")
}

subject {
Expand Down
6 changes: 6 additions & 0 deletions patterns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Amazon EKS Blueprints Teams

- [Cluster Admin](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/cluster-admin)
- [Namespaced Admin](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/namespaced-admin)
- [Development Team](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/patterns/development-team)
- [Multiple Application Teams](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams/tree/main/multiple-app-teams)
Loading