2019-10-16 13:05:14 -07:00
---
2022-12-08 15:41:39 -08:00
title_tag: Kubernetes Identity & Access Management | Crosswalk
meta_desc: An overview of cloud identity and access management providers when using Kubernetes.
2023-05-15 15:25:28 -07:00
title: IAM
h1: Kubernetes identity and access management (IAM)
2023-06-08 16:15:52 -07:00
meta_image: /images/docs/meta-images/docs-clouds-kubernetes-meta-image.png
2023-05-15 15:25:28 -07:00
menu:
clouds:
parent: kubernetes-guides
identifier: kubernetes-guides-iam
weight: 11
aliases:
- /docs/guides/crosswalk/kubernetes/identity/
2019-10-16 13:05:14 -07:00
---
2020-03-23 21:06:03 -07:00
{{< chooser cloud " aws , azure , gcp " / > }}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud aws %}}
2019-10-16 18:07:14 -07:00
2019-10-16 13:05:14 -07:00
AWS exposes an [Identity Access and Management (IAM)][iam] API which can be used to grant
2019-10-28 18:41:35 -07:00
permissions to both human and bot users. Using this API, [IAM User][users] accounts can be
slotted into [IAM Groups][groups] (e.g., the `networkAdmins` IAM Group), which can then be
allocated baseline permissions using [IAM Policies][policies].
2019-10-16 13:05:14 -07:00
2019-10-28 18:41:35 -07:00
AWS workloads (e.g., AWS Lambdas) can also be granted permissions temporarily, without the need for usernames and passwords, using [IAM Roles][roles].
2019-10-16 13:05:14 -07:00
In [Crosswalk for AWS][crosswalk-aws] we showcase how to define IAM:
2019-12-18 09:59:20 -08:00
- [Users][iam-users]
- [Groups][iam-groups]
- [Roles][iam-roles]
- [Policies][iam-policies]
2019-10-16 13:05:14 -07:00
The full code for this stack is on [GitHub][gh-repo-stack].
2019-12-18 09:59:20 -08:00
<!-- markdownlint - disable url -->
2019-10-16 18:07:14 -07:00
[iam]: https://aws.amazon.com/iam/
[users]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html
[groups]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html
[roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
[policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html
2023-05-15 16:50:57 -07:00
[crosswalk-aws]: /docs/clouds/aws/guides/
2023-05-15 15:25:28 -07:00
[iam-users]: /docs/clouds/aws/guides/iam/#iam -users
[iam-groups]: /docs/clouds/aws/guides/iam/#iam -groups
[iam-roles]: /docs/clouds/aws/guides/iam/#iam -roles
[iam-policies]: /docs/clouds/aws/guides/iam/#using -the-policydocument-interface
2019-11-13 09:53:50 -08:00
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/aws/01-identity
2019-12-18 09:59:20 -08:00
<!-- markdownlint - enable url -->
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
{{% choosable cloud azure %}}
2019-10-16 18:07:14 -07:00
2019-10-28 18:41:35 -07:00
Azure exposes an [Active Directory][azure-iam] API which can be used to grant
permissions to both human and bot users. Using this API, [IAM User][azure-users] accounts can be
slotted into [IAM Groups][azure-groups] (e.g., the `networkAdmins` IAM Group), which can then be
allocated baseline permissions using [IAM Permissions][azure-permissions].
Azure services can also be granted permissions temporarily, without the need for usernames and passwords, using [Applications and ServicePrincipals][azure-sp].
2019-10-16 18:07:14 -07:00
The full code for this stack is on [GitHub][gh-repo-stack].
2019-12-18 09:59:20 -08:00
<!-- markdownlint - disable url -->
2019-10-28 18:41:35 -07:00
[azure-iam]: https://azure.microsoft.com/en-us/services/active-directory/
[azure-users]: https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-overview-user-model
[azure-groups]: https://docs.microsoft.com/en-us/azure/active-directory/users-groups-roles/directory-overview-user-model
[azure-roles]: https://docs.microsoft.com/en-us/azure/role-based-access-control/rbac-and-directory-admin-roles?context=azure/active-directory/users-groups-roles/context/ugr-context
[azure-permissions]: https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/users-default-permissions?context=azure/active-directory/users-groups-roles/context/ugr-context
[azure-sp]: https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals
2019-11-13 09:53:50 -08:00
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/azure/01-identity
2019-12-18 09:59:20 -08:00
<!-- markdownlint - enable url -->
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
{{% choosable cloud gcp %}}
2019-10-16 18:07:14 -07:00
2023-05-15 15:25:28 -07:00
Google Cloud exposes an [Identity Access and Management (IAM)][gcp-iam] API which can be used to grant
2019-10-29 15:10:16 -07:00
permissions to both human and bot users. Using this API, [IAM Members][gcp-iam] can be
slotted into end users, [IAM Groups][gcp-iam] (e.g., the `networkAdmins` IAM Group),
and GSuite accounts, and can then be allocated [IAM Roles][gcp-roles] with baseline permissions using [IAM Policies][gcp-policies].
2023-05-15 15:25:28 -07:00
Google Cloud services can also be granted permissions temporarily, without the need for usernames and passwords, using [ServiceAccounts][gcp-sa].
2019-10-16 18:07:14 -07:00
The full code for this stack is on [GitHub][gh-repo-stack].
2019-12-18 09:59:20 -08:00
<!-- markdownlint - disable url -->
2019-10-29 15:10:16 -07:00
[gcp-iam]: https://cloud.google.com/iam/docs/overview
[gcp-policies]: https://cloud.google.com/iam/docs/reference/rest/v1/Policy
[gcp-roles]: https://cloud.google.com/iam/docs/understanding-roles
[gcp-members]: https://cloud.google.com/iam/docs/overview
[gcp-sa]: https://cloud.google.com/iam/docs/service-accounts
2019-11-13 09:53:50 -08:00
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/gcp/01-identity
2019-12-18 09:59:20 -08:00
<!-- markdownlint - enable url -->
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
{{% choosable cloud aws %}}
2019-10-16 18:07:14 -07:00
## Overview
We'll review how to:
2019-12-18 09:59:20 -08:00
- [Create an IAM Role for Admins ](#create-an-iam-role-for-admins )
- [Create an IAM Role for Developers ](#create-an-iam-role-for-developers )
- [Create IAM Roles for EKS Node Groups ](#create-iam-roles-for-eks-node-groups )
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud azure %}}
2019-10-16 18:07:14 -07:00
## Overview
We'll review how to:
2019-12-18 09:59:20 -08:00
- [Create an IAM Server Application and ServicePrincipal ](#create-an-iam-server-application-and-serviceprincipal )
- [Create an IAM Client Application and ServicePrincipal ](#create-an-iam-server-application-and-serviceprincipal )
- [Create an IAM Group for Developers ](#create-an-iam-group-for-developers )
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud gcp %}}
2019-10-16 18:07:14 -07:00
## Overview
We'll review how to:
2019-12-18 09:59:20 -08:00
- [Create an IAM Role and ServiceAccount for Admins ](#create-an-iam-role-and-serviceaccount-for-admins )
- [Create an IAM Role for Managing CloudSQL Databases ](#create-an-iam-role-for-managing-cloudsql-databases )
- [Create an IAM Role and ServiceAccount for Developers ](#create-an-iam-role-and-serviceaccount-for-developers )
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud aws %}}
2019-10-16 13:05:14 -07:00
2019-10-28 18:41:35 -07:00
## Create an IAM Role for Admins
2019-10-30 12:19:58 -07:00
Create an admin role in AWS that assumes the AWS account caller, and attach EKS admin policies to the role.
2019-10-29 15:10:16 -07:00
This role will be mapped into the [`system:masters` ][k8s-sys-masters] group in Kubernetes RBAC.
2019-10-16 13:05:14 -07:00
```typescript
import * as aws from "@pulumi/aws ";
// Create the EKS cluster admins role.
const adminsName = "admins";
const adminsIamRole = new aws.iam.Role(`${adminsName}-eksClusterAdmin` , {
assumeRolePolicy: aws.getCallerIdentity().then(id =>
aws.iam.assumeRolePolicyForPrincipal({"AWS": `arn:aws:iam::${id.accountId}:root` }))
})
const adminsIamRolePolicy = new aws.iam.RolePolicy(`${adminsName}-eksClusterAdminPolicy` , {
role: adminsIamRole,
policy: {
Version: "2012-10-17",
Statement: [
{ Effect: "Allow", Action: ["eks:*", "ec2:DescribeImages"], Resource: "*", },
{ Effect: "Allow", Action: "iam:PassRole", Resource: "*"},
],
},
},
{ parent: adminsIamRole },
);
```
2019-11-07 14:29:26 -08:00
Authenticate as the admin role.
```bash
$ aws sts assume-role --role-arn `pulumi stack output adminsIamRoleArn` --role-session-name k8s-admin
```
2019-10-18 14:37:17 -07:00
[k8s-sys-masters]: https://kubernetes.io/docs/reference/access-authn-authz/rbac#user -facing-roles
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
{{% choosable cloud azure %}}
2019-10-16 18:07:14 -07:00
2019-10-28 18:41:35 -07:00
Azure AD integration with AKS requires that two Azure AD application objects be
created: a server component to provide authentication, and a client component
2019-11-05 12:18:24 -08:00
used by the CLI for authentication that works with the server component. We
will create both in the sections below.
> Note: The Server and Client Application registrations will be created with the desired accesses, but an administrator
2019-11-12 12:53:44 -08:00
**will need** to grant the Server Application consent before they can be used in proceeding stacks.
2019-10-28 18:41:35 -07:00
See the official [docs][azure-ad-aks] for more details.
2019-11-05 12:18:24 -08:00
### Prerequisites
To facilitate working with Azure, it is recommended that you create a new
ServicePrincipal with the proper permissions needed to create all of the
resources in each stack.
```bash
$ az ad sp create-for-rbac --name MyServicePrincipal
2019-11-05 12:18:24 -08:00
$ az login --service-principal --username $ARM_CLIENT_ID --password $ARM_CLIENT_SECRET --tenant $ARM_TENANT_ID
2019-11-05 12:18:24 -08:00
```
2019-11-11 18:54:48 -08:00
Ensure the ServicePrincipal has the following permissions for the legacy, and current Graph APIs:
2019-11-05 12:18:24 -08:00
2019-12-18 09:59:20 -08:00
#### **Azure Active Directory Graph (Legacy)**
2019-11-05 12:18:24 -08:00
| Permission Name | Type |
|---|---|
|Application.ReadWrite.All | Application |
|Directory.ReadWrite.All | Application |
|Group.ReadWrite.All | Delegated |
|User.Read.All | Delegated |
2019-12-18 09:59:20 -08:00
#### **Microsoft Graph**
2019-11-05 12:18:24 -08:00
| Permission Name | Type |
|---|---|
|Application.ReadWrite.All | Application |
|Directory.ReadWrite.All | Application |
|Group.ReadWrite.All | Delegated |
|User.Read | Delegated |
2019-10-28 18:41:35 -07:00
## Create an IAM Server Application and ServicePrincipal
2019-10-16 18:07:14 -07:00
2019-10-30 12:19:58 -07:00
Create an Azure server Application and ServicePrincipal, and attach it AD
permissions.
2019-11-05 12:18:24 -08:00
> Note: The Application registration will be created with the desired accesses, but an administrator
**will need** to grant consent before they can be used in proceeding stacks.
2019-10-16 18:07:14 -07:00
```typescript
2019-10-28 18:41:35 -07:00
import * as azuread from "@pulumi/azuread ";
// Create the server application in Azure AD.
const applicationServer = new azuread.Application(`${name}-app-server` , {
replyUrls: ["http://k8s_server"],
type: "webapp/api",
groupMembershipClaims: "All",
requiredResourceAccesses: [
// Windows Azure Active Directory API
{
resourceAppId: "00000002-0000-0000-c000-000000000000",
resourceAccesses: [{
// DELEGATED PERMISSIONS: "Sign in and read user profile"
id: "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
type: "Scope",
}],
},
// MicrosoftGraph API
{
resourceAppId: "00000003-0000-0000-c000-000000000000",
resourceAccesses: [
// APPLICATION PERMISSIONS: "Read directory data"
{
id: "7ab1d382-f21e-4acd-a863-ba3e13f7da61",
type: "Role",
},
// DELEGATED PERMISSIONS: "Sign in and read user profile"
{
id: "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
type: "Scope",
},
// DELEGATED PERMISSIONS: "Read directory data"
{
id: "06da0dbc-49e2-44d2-8312-53f166ab848a",
type: "Scope",
},
],
},
],
});
// Create the server application Service Principal.
const principalServer = new azuread.ServicePrincipal(`${name}-sp-server` , {
applicationId: applicationServer.applicationId,
});
// Export outputs.
export const adServerAppId = applicationServer.applicationId;
```
## Create an IAM Client Application and ServicePrincipal
2019-10-30 12:19:58 -07:00
Create an Azure client Application and ServicePrincipal, and attach it AD
permissions.
2019-10-28 18:41:35 -07:00
```typescript
import * as azuread from "@pulumi/azuread ";
// Create the client application in Azure AD.
const applicationClient = new azuread.Application(`${name}-app-client` , {
replyUrls: ["http://k8s_server"],
type: "native",
requiredResourceAccesses: [
// Windows Azure Active Directory API
{
resourceAppId: "00000002-0000-0000-c000-000000000000",
resourceAccesses: [{
// DELEGATED PERMISSIONS: "Sign in and read user profile"
id: "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
type: "Scope",
}],
},
// AKS ad application server
{
resourceAppId: applicationServer.applicationId,
resourceAccesses: [{
// Server app Oauth2 permissions id
id: applicationServer.oauth2Permissions[0].id,
type: "Scope",
}],
},
],
});
// Create the client application Service Principal.
const principalClient = new azuread.ServicePrincipal(`${name}-sp-client` , {
applicationId: applicationClient.applicationId,
});
// Export outputs.
export const adClientAppId = applicationClient.applicationId;
2019-10-16 18:07:14 -07:00
```
2019-10-16 13:05:14 -07:00
2019-10-28 18:41:35 -07:00
[azure-ad-aks]: https://docs.microsoft.com/en-us/azure/aks/azure-ad-integration
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
{{% choosable cloud gcp %}}
2019-10-16 18:07:14 -07:00
2019-11-12 15:04:20 -08:00
See the official [docs][gke-rbac] for more details.
[gke-rbac]: https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control
### Prerequisites
2023-05-15 15:25:28 -07:00
To facilitate working with Google Cloud, it is recommended that you create a new
2019-11-12 15:04:20 -08:00
ServiceAccount with the proper permissions needed to create all of the
2023-05-15 15:25:28 -07:00
resources in each stack. We'll set this ServiceAccount to be bound to [Google Cloud roles][gcp-roles]
2019-11-12 15:04:20 -08:00
the with permissions of `role/editor` and `roles/container.clusterAdmin` .
Create the ServiceAccount and its secret key to use for auth. Then bind it to
the `roles/editor` role, and authenticate as the ServiceAccount to use with the stacks.
```bash
$ gcloud iam service-accounts create my-service-account --description MyServiceAccount --display-name MyServiceAccount
$ gcloud iam service-accounts keys create ~/key.json --iam-account my-service-account@pulumi -development.iam.gserviceaccount.com
2020-10-23 17:47:12 +01:00
$ gcloud projects add-iam-policy-binding pulumi-development --member serviceAccount:my-service-account@pulumi -development.iam.gserviceaccount.com --role roles/editor
$ gcloud projects add-iam-policy-binding pulumi-development --member serviceAccount:my-service-account@pulumi -development.iam.gserviceaccount.com --role roles/container.clusterAdmin
2019-11-12 15:04:20 -08:00
$ gcloud auth activate-service-account --key-file ~/key.json
```
[gcp-roles]: https://cloud.google.com/iam/docs/understanding-roles
2019-10-29 15:10:16 -07:00
## Create an IAM Role and ServiceAccount for Admins
2023-05-15 15:25:28 -07:00
Create an admin role in Google Cloud and attach admin policies to the role.
2019-10-29 15:10:16 -07:00
This role will be bound to the admin service account.
2019-10-16 18:07:14 -07:00
```typescript
2019-10-29 15:10:16 -07:00
import * as gcp from "@pulumi/gcp ";
2019-11-07 11:52:49 -08:00
// Create the GKE cluster admins ServiceAccount.
const adminsName = "admins";
const adminsIamServiceAccount = new gcp.serviceAccount.Account(adminsName, {
2019-10-29 15:10:16 -07:00
project: config.project,
2019-11-07 11:52:49 -08:00
accountId: `k8s-${adminsName}` ,
displayName: "Kubernetes Admins",
2019-10-29 15:10:16 -07:00
});
2019-11-07 11:52:49 -08:00
// Bind the admin ServiceAccount to be a GKE cluster admin.
2019-11-07 13:44:04 -08:00
util.bindToRole(`${adminsName}-k8s` , adminsIamServiceAccount, {
2019-10-29 15:10:16 -07:00
project: config.project,
2019-11-07 13:44:04 -08:00
roles: ["roles/container.clusterAdmin", "roles/container.developer"],
2019-10-29 15:10:16 -07:00
});
2019-11-07 11:52:49 -08:00
// Bind the admin ServiceAccount to be a CloudSQL admin.
2019-11-07 13:44:04 -08:00
util.bindToRole(`${adminsName}-cloudsql` , adminsIamServiceAccount, {
2019-11-07 11:52:49 -08:00
project: config.project,
2019-11-07 13:44:04 -08:00
roles: ["roles/cloudsql.admin"],
2019-11-07 11:52:49 -08:00
});
// Export the admins ServiceAccount key.
const adminsIamServiceAccountKey = util.createServiceAccountKey(`${adminsName}Key` , adminsIamServiceAccount);
2019-11-07 13:44:04 -08:00
// Export the admins ServiceAccount client secret to authenticate as this service account.
export const adminsIamServiceAccountSecret = util.clientSecret(adminsIamServiceAccountKey);
2019-10-29 15:10:16 -07:00
// Helper to bind the service account to a given role.
export function bindToRole(
name: string,
sa: gcp.serviceAccount.Account,
2019-11-07 13:44:04 -08:00
args: { project: pulumi.Input< string > ; roles: string[]})
{
args.roles.forEach((role, index) => {
new gcp.projects.IAMBinding(`${name}-${index}` , {
project: args.project,
role: role,
members: [sa.email.apply(email => `serviceAccount:${email}` )],
});
})
2019-10-29 15:10:16 -07:00
}
// Helper to create new service account key.
2019-11-07 11:52:49 -08:00
export function createServiceAccountKey(name: string, sa: gcp.serviceAccount.Account): gcp.serviceAccount.Key {
2019-10-29 15:10:16 -07:00
return new gcp.serviceAccount.Key(name, { serviceAccountId: sa.name });
}
// Helper to export service account for authentication use.
2019-11-12 13:21:02 -08:00
export function clientSecret(key: gcp.serviceAccount.Key): pulumi.Output< any > {
2019-10-29 15:10:16 -07:00
return key.privateKey.apply(key => JSON.parse(Buffer.from(key, "base64").toString("ascii")));
}
```
2019-11-07 13:44:04 -08:00
Authenticate as the admin ServiceAccount by exporting the key, and signing
2019-10-29 15:10:16 -07:00
into gcloud with it.
```bash
2019-11-07 11:52:49 -08:00
$ pulumi stack output adminsIamServiceAccountSecret > k8s-admin-sa-key.json
2019-11-07 13:44:04 -08:00
$ gcloud auth activate-service-account --key-file k8s-admin-sa-key.json
2019-10-16 18:07:14 -07:00
```
2019-10-29 15:10:16 -07:00
## Create an IAM Role for Managing CloudSQL Databases
```typescript
import * as gcp from "@pulumi/gcp ";
2019-11-07 13:44:04 -08:00
// Bind the admin ServiceAccount to be a CloudSQL admin.
util.bindToRole(`${adminsName}CloudSqlAdmin` , adminsIamServiceAccount, {
2019-10-29 15:10:16 -07:00
project: config.project,
2019-11-07 13:44:04 -08:00
roles: ["roles/cloudsql.admin"],
2019-10-29 15:10:16 -07:00
});
```
[k8s-sys-masters]: https://kubernetes.io/docs/reference/access-authn-authz/rbac#user -facing-roles
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
{{% choosable cloud aws %}}
2019-10-16 13:05:14 -07:00
2019-10-28 18:41:35 -07:00
## Create an IAM Role for Developers
2019-10-16 13:05:14 -07:00
Create a developer role in AWS that assumes the AWS account caller.
This role will be mapped into a limited developer role in Kubernetes RBAC.
```typescript
import * as aws from "@pulumi/aws ";
// Create the EKS cluster developers role.
const devName = "devs";
const devsIamRole = new aws.iam.Role(`${devName}-eksClusterDeveloper` , {
assumeRolePolicy: aws.getCallerIdentity().then(id =>
aws.iam.assumeRolePolicyForPrincipal({"AWS": `arn:aws:iam::${id.accountId}:root` }))
})
```
2019-11-07 14:29:26 -08:00
Authenticate as the devs role.
```bash
$ aws sts assume-role --role-arn `pulumi stack output devsIamRoleArn` --role-session-name k8s-devs
```
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud azure %}}
2019-10-16 18:07:14 -07:00
2019-11-07 13:44:04 -08:00
## Create an IAM Group for Admins
Create an admins group in Azure. This group will be mapped into the `system:masters` group in Kubernetes RBAC.
```typescript
import * as azure from "@pulumi/azure ";
import * as azuread from "@pulumi/azuread ";
const clientConfig = azure.core.getClientConfig();
const currentPrincipal = clientConfig.objectId;
const admins = new azuread.Group("admins", {
name: "pulumi:admins",
members: [
currentPrincipal,
],
});
```
2019-10-28 18:41:35 -07:00
## Create an IAM Group for Developers
2019-10-16 18:07:14 -07:00
2019-10-30 12:19:58 -07:00
Create a developer group in Azure. This group will be mapped into a limited
developer role in Kubernetes RBAC.
2019-11-12 12:53:44 -08:00
Add a new user in AD, or get an existing user to add to the new AD group.
2019-11-12 11:14:14 -08:00
> Note: On deletion of this Pulumi stack you **cannot** use the
> ServicePrincipal to delete the Group, as [ActiveDirectory][so-ad-no-apps] does not allow
> Application registrations to delete AD Groups. Instead, you must authenticate as a
> user, and ensure that the user has `admin` rights in AD to be able to
> delete the group.
[so-ad-no-apps]: https://stackoverflow.com/questions/46604721/azure-ad-delete-user-group-unauthorized
2019-10-16 18:07:14 -07:00
```typescript
2019-10-28 18:41:35 -07:00
import * as azuread from "@pulumi/azuread ";
2019-11-07 13:44:04 -08:00
/* Create a new user in AD.
const dev = new azuread.User("k8s-dev", {
userPrincipalName: "k8sdev@example .com",
displayName: "Kubernetes Dev",
password: "Qjker21!G",
});
*/
2019-11-07 14:23:04 -08:00
// Get an existing AD user.
2019-11-07 13:44:04 -08:00
const dev = azuread.getUser({
userPrincipalName: "alice@example .com",
});
2019-10-28 18:41:35 -07:00
// Create the AD group for Developers.
const devs = new azuread.Group("devs", {
2021-11-19 14:33:05 -05:00
displayName: "pulumi:devs",
// Assign a new or existing user to the group.
members: dev.then(d => [d.objectId]),
2019-10-28 18:41:35 -07:00
});
// Export outputs.
2021-11-19 14:33:05 -05:00
export const adGroupDevs = devs.displayName;
2019-10-16 18:07:14 -07:00
```
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud gcp %}}
2019-10-16 18:07:14 -07:00
2019-10-29 15:10:16 -07:00
## Create an IAM Role and ServiceAccount for Developers
2023-05-15 15:25:28 -07:00
Create a developer role in Google Cloud that will be mapped into a limited developer
2019-10-29 15:10:16 -07:00
role in Kubernetes RBAC.
2019-10-16 18:07:14 -07:00
```typescript
2019-10-29 15:10:16 -07:00
import * as gcp from "@pulumi/gcp ";
2019-11-07 11:52:49 -08:00
// Create the GKE cluster developers ServiceAccount.
2019-11-07 13:44:04 -08:00
const devsName = "devs";
const devsIamServiceAccount = new gcp.serviceAccount.Account(devsName, {
2019-10-29 15:10:16 -07:00
project: config.project,
2019-11-07 13:44:04 -08:00
accountId: `k8s-${devsName}` ,
2019-11-07 11:52:49 -08:00
displayName: "Kubernetes Developers",
2019-10-29 15:10:16 -07:00
});
2019-11-07 11:52:49 -08:00
// Bind the devs ServiceAccount to be a GKE cluster developer.
2019-11-07 13:44:04 -08:00
util.bindToRole(`${devsName}-k8s` , devsIamServiceAccount, {
2019-10-29 15:10:16 -07:00
project: config.project,
2019-11-07 13:44:04 -08:00
roles: ["roles/container.developer"],
2019-10-29 15:10:16 -07:00
});
2019-11-07 11:52:49 -08:00
// Export the devs ServiceAccount key.
2019-11-07 13:44:04 -08:00
const devsIamServiceAccountKey = util.createServiceAccountKey(`${devsName}Key` , devsIamServiceAccount);
2019-11-07 11:52:49 -08:00
// Export the devs ServiceAccount client secret to authenticate as this service account.
export const devsIamServiceAccountClientSecret = util.clientSecret(devsIamServiceAccountKey);
2019-10-29 15:10:16 -07:00
```
2019-11-07 13:44:04 -08:00
Authenticate as the dev ServiceAccount by exporting the key, and signing
2019-10-29 15:10:16 -07:00
into gcloud with it.
```bash
2019-11-07 11:52:49 -08:00
$ pulumi stack output devsIamServiceAccountSecret > k8s-devs-sa-key.json
$ gcloud auth activate-service-account --key-file k8s-devs-sa-key.json
2019-10-16 18:07:14 -07:00
```
2020-03-20 09:32:19 -07:00
{{% /choosable %}}
2019-10-16 18:07:14 -07:00
2020-03-20 09:32:19 -07:00
{{% choosable cloud aws %}}
2019-10-28 18:41:35 -07:00
2019-10-16 18:07:14 -07:00
## Create IAM Roles for EKS Node Groups
2019-10-16 13:05:14 -07:00
Create a node group worker role in AWS that assumes the EC2 Service, and attach
required EKS cluster polices to the role. This role will be used by the node group in an
instance profile during cluster configuration and creation.
```typescript
// The managed policies EKS requires of nodegroups join a cluster.
const nodegroupManagedPolicyArns: string[] = [
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
];
// Create the standard node group worker role and attach the required policies.
2019-10-23 13:04:17 -07:00
const stdName = "standardNodeGroup";
const stdNodegroupIamRole = new aws.iam.Role(`${stdName}-eksClusterWorkerNode` , {
2019-10-16 13:05:14 -07:00
assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({"Service": "ec2.amazonaws.com"})
})
2019-10-23 13:04:17 -07:00
attachPoliciesToRole(stdName, stdNodegroupIamRole, nodegroupManagedPolicyArns);
2019-10-16 13:05:14 -07:00
// Create the performant node group worker role and attach the required policies.
2019-10-23 13:04:17 -07:00
const perfName = "performanceNodeGroup";
const perfNodegroupIamRole = new aws.iam.Role(`${perfName}-eksClusterWorkerNode` , {
2019-10-16 13:05:14 -07:00
assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({"Service": "ec2.amazonaws.com"})
})
2019-10-23 13:04:17 -07:00
attachPoliciesToRole(perfName, perfNodegroupIamRole, nodegroupManagedPolicyArns);
2019-10-16 13:05:14 -07:00
// Attach policies to a role.
function attachPoliciesToRole(name: string, role: aws.iam.Role, policyArns: string[]) {
for (const policyArn of policyArns) {
new aws.iam.RolePolicyAttachment(`${name}-${policyArn.split('/')[1]}` ,
{ policyArn: policyArn, role: role },
);
}
}
```
2020-03-20 09:32:19 -07:00
{{% /choosable %}}