-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
aws-auth.ts
122 lines (110 loc) · 3.43 KB
/
aws-auth.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import * as iam from '@aws-cdk/aws-iam';
import { Construct, Lazy, Stack } from '@aws-cdk/core';
import { AwsAuthMapping } from './aws-auth-mapping';
import { Cluster } from './cluster';
import { KubernetesResource } from './k8s-resource';
/**
* Configuration props for the AwsAuth construct.
*/
export interface AwsAuthProps {
/**
* The EKS cluster to apply this configuration to.
*
* [disable-awslint:ref-via-interface]
*/
readonly cluster: Cluster;
}
/**
* Manages mapping between IAM users and roles to Kubernetes RBAC configuration.
*
* @see https://docs.aws.amazon.com/en_us/eks/latest/userguide/add-user-role.html
*/
export class AwsAuth extends Construct {
private readonly stack: Stack;
private readonly roleMappings = new Array<{ role: iam.IRole, mapping: AwsAuthMapping }>();
private readonly userMappings = new Array<{ user: iam.IUser, mapping: AwsAuthMapping }>();
private readonly accounts = new Array<string>();
constructor(scope: Construct, id: string, props: AwsAuthProps) {
super(scope, id);
this.stack = Stack.of(this);
new KubernetesResource(this, 'manifest', {
cluster: props.cluster,
manifest: [
{
apiVersion: 'v1',
kind: 'ConfigMap',
metadata: {
name: 'aws-auth',
namespace: 'kube-system',
},
data: {
mapRoles: this.synthesizeMapRoles(),
mapUsers: this.synthesizeMapUsers(),
mapAccounts: this.synthesizeMapAccounts(),
},
},
],
});
}
/**
* Adds the specified IAM role to the `system:masters` RBAC group, which means
* that anyone that can assume it will be able to administer this Kubernetes system.
*
* @param role The IAM role to add
* @param username Optional user (defaults to the role ARN)
*/
public addMastersRole(role: iam.IRole, username?: string) {
this.addRoleMapping(role, {
username,
groups: [ 'system:masters' ],
});
}
/**
* Adds a mapping between an IAM role to a Kubernetes user and groups.
*
* @param role The IAM role to map
* @param mapping Mapping to k8s user name and groups
*/
public addRoleMapping(role: iam.IRole, mapping: AwsAuthMapping) {
this.roleMappings.push({ role, mapping });
}
/**
* Adds a mapping between an IAM user to a Kubernetes user and groups.
*
* @param user The IAM user to map
* @param mapping Mapping to k8s user name and groups
*/
public addUserMapping(user: iam.IUser, mapping: AwsAuthMapping) {
this.userMappings.push({ user, mapping });
}
/**
* Additional AWS account to add to the aws-auth configmap.
* @param accountId account number
*/
public addAccount(accountId: string) {
this.accounts.push(accountId);
}
private synthesizeMapRoles() {
return Lazy.anyValue({
produce: () => this.stack.toJsonString(this.roleMappings.map(m => ({
rolearn: m.role.roleArn,
username: m.mapping.username ?? m.role.roleArn,
groups: m.mapping.groups,
}))),
});
}
private synthesizeMapUsers() {
return Lazy.anyValue({
produce: () => this.stack.toJsonString(this.userMappings.map(m => ({
userarn: m.user.userArn,
username: m.mapping.username ?? m.user.userArn,
groups: m.mapping.groups,
}))),
});
}
private synthesizeMapAccounts() {
return Lazy.anyValue({
produce: () => this.stack.toJsonString(this.accounts),
});
}
}