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 AWS IAM Identity Center with CAM pattern #1897

Merged
merged 9 commits into from
Apr 9, 2024
Merged
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
7 changes: 7 additions & 0 deletions docs/patterns/sso-iam-identity-center-cam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: SSO - IAM Identity Center
---

{%
include-markdown "../../patterns/sso-iam-identity-center/README.md"
%}
39 changes: 23 additions & 16 deletions patterns/sso-iam-identity-center/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# IAM Identity Center Single Sign-On for Amazon EKS Cluster
# IAM Identity Center Single Sign-On for Amazon EKS Cluster with Cluster Access Manager

This example demonstrates how to deploy an Amazon EKS cluster that is deployed on the AWS Cloud, integrated with IAM Identity Center (former AWS SSO) as an the Identity Provider (IdP) for Single Sign-On (SSO) authentication. The configuration for authorization is done using Kubernetes Role-based access control (RBAC).
This example demonstrates how to deploy an Amazon EKS cluster that is deployed on the AWS Cloud, integrated with IAM Identity Center (former AWS SSO) as an the Identity Provider (IdP) for Single Sign-On (SSO) authentication having [Cluster Access Manager](https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-eks-controls-iam-cluster-access-management/) as the entry point API. The configuration to provide authorization for users is simplified using a combination of [Access Entries](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html) and Kubernetes Role-based access control (RBAC).

## Deploy

Expand All @@ -14,10 +14,11 @@ To do that use the link provided in the email invite - *if you added a valid ema

With the active users, use one of the `terraform output` examples to configure your AWS credentials for SSO, as shown in the examples below. After you choose the *SSO registration scopes*, your browser windows will appear and request to login using your IAM Identity Center username and password.

**Admin user example**
```
### Admin user example

```sh
configure_sso_admin = <<EOT
# aws configure sso
# aws configure sso --profile EKSClusterAdmin
SSO session name (Recommended): <SESSION_NAME>
SSO start URL [None]: https://d-1234567890.awsapps.com/start
SSO region [None]: us-west-2
Expand All @@ -39,15 +40,17 @@ configure_sso_admin = <<EOT

To use this profile, specify the profile name using --profile, as shown:

aws eks --region us-west-2 update-kubeconfig --name iam-identity-center --profile EKSClusterAdmin-123456789012
aws eks --region us-west-2 update-kubeconfig --name iam-identity-center --profile EKSClusterAdmin


EOT
```

**Read-only user example**
```
### Read-only user example

```sh
configure_sso_user = <<EOT
# aws configure sso
# aws configure sso --profile EKSClusterUser
SSO session name (Recommended): <SESSION_NAME>
SSO start URL [None]: https://d-1234567890.awsapps.com/start
SSO region [None]: us-west-2
Expand All @@ -69,14 +72,14 @@ configure_sso_user = <<EOT

To use this profile, specify the profile name using --profile, as shown:

aws eks --region us-west-2 update-kubeconfig --name iam-identity-center --profile EKSClusterUser-123456789012
aws eks --region us-west-2 update-kubeconfig --name iam-identity-center --profile EKSClusterUser

EOT
```

With the `kubeconfig` configured, you'll be able to run `kubectl` commands in your Amazon EKS Cluster with the impersonated user. The read-only user has a `cluster-viewer` Kubernetes role bound to it's group, whereas the admin user, has the `admin` Kubernetes role bound to it's group.

```
```sh
kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
amazon-guardduty aws-guardduty-agent-bl2v2 1/1 Running 0 3h54m
Expand All @@ -92,14 +95,18 @@ kube-system kube-proxy-p4f5g 1/1 Running 0 3h54
kube-system kube-proxy-q1fmc 1/1 Running 0 3h54m
```

You can also use the `configure_kubectl` output to assume the *Cluster creator* role with `cluster-admin` access.
If not revoked after the cluster creation, it's possible to use the `configure_kubectl` output to assume the *Cluster creator* role with `cluster-admin` access.

```
```sh
configure_kubectl = "aws eks --region us-west-2 update-kubeconfig --name iam-identity-center"
```

## Destroy

{%
include-markdown "../../docs/_partials/destroy.md"
%}
If you revoked the *Cluster creator* `cluster-admin` permission, you may need to re-associate the `AmazonEKSClusterAdminPolicy` access entry to run `terraform destroy`.

```sh
terraform destroy -target module.developers_team -auto-approve
terraform destroy -target module.eks -auto-approve
terraform destroy -auto-approve
```
60 changes: 50 additions & 10 deletions patterns/sso-iam-identity-center/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ provider "aws" {
region = local.region
}

provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)

exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}

data "aws_availability_zones" "available" {}

locals {
name = basename(path.cwd)
name = "sso-${basename(path.cwd)}"
region = "us-west-2"

vpc_cidr = "10.0.0.0/16"
Expand All @@ -23,7 +35,7 @@ locals {

module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.21"
version = "~> 20.0"

cluster_name = local.name
cluster_version = "1.29"
Expand All @@ -48,14 +60,42 @@ module "eks" {
desired_size = 3
}
}

manage_aws_auth_configmap = true
aws_auth_roles = flatten(
[
module.operators_team.aws_auth_configmap_role,
module.developers_team.aws_auth_configmap_role,
]
)
# Give the Terraform identity admin access to the cluster just for the deployment phase.
# You can revoke this permissions cluster is created since the below referenced "operators" have the same access level
enable_cluster_creator_admin_permissions = true

# This will set the cluster authentication use API only, meaning that the `aws-auth` configMap will not work on this example.
authentication_mode = "API"

access_entries = {
# One access entry with a policy associated
operators = {
principal_arn = tolist(data.aws_iam_roles.admin.arns)[0]

policy_associations = {
operators = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
access_scope = {
type = "cluster"
}
}
}
},
developers = {
kubernetes_groups = ["eks-developers"]
principal_arn = tolist(data.aws_iam_roles.user.arns)[0]

policy_associations = {
developers = {
policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
access_scope = {
namespaces = ["default"]
type = "namespace"
}
}
}
}
}

tags = local.tags
}
Expand Down
4 changes: 2 additions & 2 deletions patterns/sso-iam-identity-center/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ output "configure_sso_admins" {
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.us-west-2.amazonaws.com/
https://device.sso.${local.region}.amazonaws.com/

Then enter the code:

Expand Down Expand Up @@ -43,7 +43,7 @@ output "configure_sso_users" {
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.us-west-2.amazonaws.com/
https://device.sso.${local.region}.amazonaws.com/

Then enter the code:

Expand Down
16 changes: 2 additions & 14 deletions patterns/sso-iam-identity-center/sso.tf
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
# Pre requisite
# Enable AWS IAM Identity Manager (https://console.aws.amazon.com/singlesignon/home/)

provider "kubernetes" {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)

exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
# This requires the awscli to be installed locally where Terraform is executed
args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name]
}
}

data "aws_caller_identity" "current" {}

data "aws_ssoadmin_instances" "this" {}
Expand All @@ -21,15 +9,15 @@ resource "aws_ssoadmin_permission_set" "admin" {
name = "EKSClusterAdmin"
description = "Amazon EKS Cluster Admins."
instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
relay_state = "https://s3.console.aws.amazon.com/s3/home?region=us-west-2#"
relay_state = "https://s3.console.aws.amazon.com/s3/home?region=${local.region}#"
session_duration = "PT1H"
}

resource "aws_ssoadmin_permission_set" "user" {
name = "EKSClusterUser"
description = "Amazon EKS Cluster Users."
instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
relay_state = "https://s3.console.aws.amazon.com/s3/home?region=us-west-2#"
relay_state = "https://s3.console.aws.amazon.com/s3/home?region=${local.region}#"
session_duration = "PT1H"
}

Expand Down
36 changes: 1 addition & 35 deletions patterns/sso-iam-identity-center/teams.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@

# Here why these local variables and datasources are needed:
# Here why these datasources are needed:
# https://docs.aws.amazon.com/singlesignon/latest/userguide/referencingpermissionsets.html
# https://repost.aws/knowledge-center/eks-configure-sso-user
locals {
sso_role_prefix = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role"
}

data "aws_iam_roles" "admin" {
name_regex = "AWSReservedSSO_EKSClusterAdmin_.*"
Expand All @@ -24,31 +21,6 @@ data "aws_iam_roles" "user" {
]
}

module "operators_team" {
source = "aws-ia/eks-blueprints-teams/aws"
version = "1.1.0"


name = "eks-operators"

enable_admin = true
cluster_arn = module.eks.cluster_arn

create_iam_role = false
iam_role_arn = "${local.sso_role_prefix}/${tolist(data.aws_iam_roles.admin.names)[0]}"
principal_arns = data.aws_iam_roles.admin.arns

tags = {
Environment = "dev"
}

depends_on = [
data.aws_iam_roles.admin,
data.aws_iam_roles.user
]

}

module "developers_team" {
source = "aws-ia/eks-blueprints-teams/aws"
version = "1.1.0"
Expand All @@ -59,7 +31,6 @@ module "developers_team" {
oidc_provider_arn = module.eks.oidc_provider_arn

create_iam_role = false
iam_role_arn = "${local.sso_role_prefix}/${tolist(data.aws_iam_roles.user.names)[0]}"
principal_arns = data.aws_iam_roles.user.arns

labels = {
Expand All @@ -71,11 +42,6 @@ module "developers_team" {
}

namespaces = {
default = {
# Provides access to the default Namespace
create = false
}

development = {
labels = {
projectName = "project-awesome",
Expand Down
Loading