@pulumi/eks 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -11
- package/cert-thumprint.d.ts +11 -11
- package/cert-thumprint.js +25 -21
- package/cert-thumprint.js.map +1 -1
- package/cluster.js +112 -88
- package/cluster.js.map +1 -1
- package/cmd/provider/cluster.js.map +1 -1
- package/cmd/provider/cni.js +101 -31
- package/cmd/provider/cni.js.map +1 -1
- package/cmd/provider/index.js +6 -10
- package/cmd/provider/index.js.map +1 -1
- package/cmd/provider/nodegroup.js.map +1 -1
- package/cmd/provider/randomSuffix.js +3 -1
- package/cmd/provider/randomSuffix.js.map +1 -1
- package/cmd/provider/securitygroup.js.map +1 -1
- package/cni/aws-k8s-cni.yaml +195 -196
- package/cni.js +3 -1
- package/cni.js.map +1 -1
- package/dashboard/heapster-rbac.yaml +7 -7
- package/dashboard/heapster.yaml +33 -33
- package/dashboard/influxdb.yaml +31 -31
- package/dashboard/kubernetes-dashboard.yaml +104 -104
- package/dashboard.js +5 -3
- package/dashboard.js.map +1 -1
- package/dependencies.js +16 -6
- package/dependencies.js.map +1 -1
- package/index.d.ts +2 -2
- package/index.js.map +1 -1
- package/nodegroup.js +132 -90
- package/nodegroup.js.map +1 -1
- package/package.json +27 -16
- package/package.json.dev +27 -16
- package/randomSuffix.js +4 -2
- package/randomSuffix.js.map +1 -1
- package/securitygroup.js +1 -4
- package/securitygroup.js.map +1 -1
- package/servicerole.js +10 -8
- package/servicerole.js.map +1 -1
- package/storageclass.d.ts +16 -16
- package/storageclass.js +7 -6
- package/storageclass.js.map +1 -1
package/README.md
CHANGED
|
@@ -7,22 +7,27 @@
|
|
|
7
7
|
|
|
8
8
|
# Pulumi Amazon Web Services (AWS) EKS Components
|
|
9
9
|
|
|
10
|
-
The Pulumi EKS library provides a Pulumi component that creates and manages the resources necessary to run an EKS Kubernetes cluster in AWS.
|
|
10
|
+
The Pulumi EKS library provides a Pulumi component that creates and manages the resources necessary to run an EKS Kubernetes cluster in AWS. This component exposes the Crosswalk for AWS functionality documented in the [Pulumi Elastic Kubernetes Service guide](https://www.pulumi.com/docs/guides/crosswalk/aws/eks/) as a package available in all Pulumi languages.
|
|
11
|
+
|
|
11
12
|
|
|
12
13
|
This includes:
|
|
13
14
|
- The EKS cluster control plane.
|
|
14
15
|
- The cluster's worker nodes configured as node groups, which are managed by an auto scaling group.
|
|
15
16
|
- The AWS CNI Plugin [`aws-k8s-cni`](https://github.com/aws/amazon-vpc-cni-k8s/) to manage pod networking in Kubernetes.
|
|
16
17
|
|
|
17
|
-
## Pre-Requisites
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
<div>
|
|
20
|
+
<a href="https://www.pulumi.com/templates/kubernetes/aws/" title="Get Started">
|
|
21
|
+
<img src="https://www.pulumi.com/images/get-started.svg?" width="120">
|
|
22
|
+
</a>
|
|
23
|
+
</div>
|
|
23
24
|
|
|
24
25
|
## Installing
|
|
25
26
|
|
|
27
|
+
This package is available in many languages in the standard packaging formats.
|
|
28
|
+
|
|
29
|
+
### Node.js (JavaScript/TypeScript)
|
|
30
|
+
|
|
26
31
|
To use from JavaScript or TypeScript in Node.js, install it using either `npm`:
|
|
27
32
|
|
|
28
33
|
```bash
|
|
@@ -56,17 +61,17 @@ To use from .NET, install using `dotnet add package`:
|
|
|
56
61
|
## References
|
|
57
62
|
|
|
58
63
|
* [Tutorial](https://www.pulumi.com/blog/easily-create-and-manage-aws-eks-kubernetes-clusters-with-pulumi/)
|
|
59
|
-
* [Reference Documentation](https://www.pulumi.com/
|
|
64
|
+
* [Reference Documentation](https://www.pulumi.com/registry/packages/eks/api-docs/)
|
|
60
65
|
* [Examples](./examples)
|
|
61
|
-
* [Crosswalk for AWS
|
|
66
|
+
* [Crosswalk for AWS - EKS Guide](https://www.pulumi.com/docs/guides/crosswalk/aws/eks/)
|
|
62
67
|
|
|
63
|
-
|
|
68
|
+
## Contributing
|
|
64
69
|
|
|
65
70
|
If you are interested in contributing, please see the [contributing docs][contributing].
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
## Code of Conduct
|
|
68
73
|
|
|
69
|
-
|
|
74
|
+
Please follow the [code of conduct][code-of-conduct].
|
|
70
75
|
|
|
71
76
|
[contributing]: CONTRIBUTING.md
|
|
72
77
|
[code-of-conduct]: CODE-OF-CONDUCT.md
|
package/cert-thumprint.d.ts
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import * as pulumi from "@pulumi/pulumi";
|
|
3
3
|
import * as http from "http";
|
|
4
4
|
/**
|
|
5
|
-
* Get the certificate thumprint of the issuing CA for the TLS enabled URL.
|
|
6
|
-
*
|
|
7
|
-
* This is used for OIDC provider configuration.
|
|
8
|
-
*
|
|
9
|
-
* See for more details:
|
|
10
|
-
* - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
|
|
11
|
-
* - https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
|
|
12
|
-
* - https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/
|
|
13
|
-
* - https://medium.com/@marcincuber/amazon-eks-with-oidc-provider-iam-roles-for-kubernetes-services-accounts-59015d15cb0c
|
|
14
|
-
* - https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/aws/eks/#enabling-iam-roles-for-service-accounts
|
|
15
|
-
*/
|
|
5
|
+
* Get the certificate thumprint of the issuing CA for the TLS enabled URL.
|
|
6
|
+
*
|
|
7
|
+
* This is used for OIDC provider configuration.
|
|
8
|
+
*
|
|
9
|
+
* See for more details:
|
|
10
|
+
* - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
|
|
11
|
+
* - https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
|
|
12
|
+
* - https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/
|
|
13
|
+
* - https://medium.com/@marcincuber/amazon-eks-with-oidc-provider-iam-roles-for-kubernetes-services-accounts-59015d15cb0c
|
|
14
|
+
* - https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/aws/eks/#enabling-iam-roles-for-service-accounts
|
|
15
|
+
*/
|
|
16
16
|
export declare function getIssuerCAThumbprint(issuerUrl: pulumi.Input<string>, agent: http.Agent): pulumi.Output<string>;
|
package/cert-thumprint.js
CHANGED
|
@@ -25,23 +25,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
25
25
|
exports.getIssuerCAThumbprint = void 0;
|
|
26
26
|
const pulumi = require("@pulumi/pulumi");
|
|
27
27
|
const https = require("https");
|
|
28
|
+
const tls = require("tls");
|
|
28
29
|
const url = require("url");
|
|
29
30
|
const THUMBPRINT_MAX_RETRIES = 12;
|
|
30
31
|
const THUMBPRINT_SLEEP_MILLISECOND_INTERVAL = 5000;
|
|
31
32
|
/**
|
|
32
|
-
* Get the certificate thumprint of the issuing CA for the TLS enabled URL.
|
|
33
|
-
*
|
|
34
|
-
* This is used for OIDC provider configuration.
|
|
35
|
-
*
|
|
36
|
-
* See for more details:
|
|
37
|
-
* - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
|
|
38
|
-
* - https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
|
|
39
|
-
* - https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/
|
|
40
|
-
* - https://medium.com/@marcincuber/amazon-eks-with-oidc-provider-iam-roles-for-kubernetes-services-accounts-59015d15cb0c
|
|
41
|
-
* - https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/aws/eks/#enabling-iam-roles-for-service-accounts
|
|
42
|
-
*/
|
|
33
|
+
* Get the certificate thumprint of the issuing CA for the TLS enabled URL.
|
|
34
|
+
*
|
|
35
|
+
* This is used for OIDC provider configuration.
|
|
36
|
+
*
|
|
37
|
+
* See for more details:
|
|
38
|
+
* - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
|
|
39
|
+
* - https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
|
|
40
|
+
* - https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/
|
|
41
|
+
* - https://medium.com/@marcincuber/amazon-eks-with-oidc-provider-iam-roles-for-kubernetes-services-accounts-59015d15cb0c
|
|
42
|
+
* - https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/aws/eks/#enabling-iam-roles-for-service-accounts
|
|
43
|
+
*/
|
|
43
44
|
function getIssuerCAThumbprint(issuerUrl, agent) {
|
|
44
|
-
return pulumi.output(issuerUrl).apply(issUrl => {
|
|
45
|
+
return pulumi.output(issuerUrl).apply((issUrl) => {
|
|
45
46
|
return getThumbprint(issUrl, THUMBPRINT_MAX_RETRIES, THUMBPRINT_SLEEP_MILLISECOND_INTERVAL, agent);
|
|
46
47
|
});
|
|
47
48
|
}
|
|
@@ -77,20 +78,23 @@ function getThumbprint(issuerUrl, retriesLeft, interval, agent) {
|
|
|
77
78
|
const req = https
|
|
78
79
|
.get(options)
|
|
79
80
|
.on("error", reject)
|
|
80
|
-
.on("socket", socket => {
|
|
81
|
+
.on("socket", (socket) => {
|
|
82
|
+
if (!(socket instanceof tls.TLSSocket)) {
|
|
83
|
+
req.emit("error", new Error("socket is not of type TLSSocket"));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
81
86
|
socket.on("secureConnect", () => {
|
|
82
87
|
const certificate = socket.getPeerCertificate(true);
|
|
83
88
|
const fingerprint = findIntRootCACertificate(certificate).fingerprint;
|
|
84
89
|
// Check if certificate is valid
|
|
85
90
|
if (socket.authorized === false) {
|
|
86
|
-
req.emit("error",
|
|
87
|
-
|
|
91
|
+
req.emit("error", socket.authorizationError);
|
|
92
|
+
req.destroy();
|
|
93
|
+
return;
|
|
88
94
|
}
|
|
89
|
-
resolve(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.join("")
|
|
93
|
-
.toLowerCase());
|
|
95
|
+
resolve(
|
|
96
|
+
// Ref: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
|
|
97
|
+
fingerprint.split(":").join("").toLowerCase());
|
|
94
98
|
});
|
|
95
99
|
});
|
|
96
100
|
req.end();
|
|
@@ -99,7 +103,7 @@ function getThumbprint(issuerUrl, retriesLeft, interval, agent) {
|
|
|
99
103
|
catch (e) {
|
|
100
104
|
if (retriesLeft) {
|
|
101
105
|
pulumi.log.info(`Waiting for cert issuer URL(${THUMBPRINT_MAX_RETRIES - retriesLeft})`, undefined, undefined, true);
|
|
102
|
-
yield new Promise(resolve => setTimeout(resolve, interval));
|
|
106
|
+
yield new Promise((resolve) => setTimeout(resolve, interval));
|
|
103
107
|
return getThumbprint(issuerUrl, retriesLeft - 1, interval, agent);
|
|
104
108
|
}
|
|
105
109
|
}
|
package/cert-thumprint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cert-thumprint.js","sourceRoot":"","sources":["../cert-thumprint.ts"],"names":[],"mappings":";AAAA,2CAA2C;AAC3C,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;;;;;;;;;;;AAEjC,yCAAyC;AAEzC,+BAA+B;
|
|
1
|
+
{"version":3,"file":"cert-thumprint.js","sourceRoot":"","sources":["../cert-thumprint.ts"],"names":[],"mappings":"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"}
|
package/cluster.js
CHANGED
|
@@ -57,42 +57,46 @@ function createOrGetInstanceProfile(name, parent, instanceRoleName, instanceProf
|
|
|
57
57
|
/** @internal */
|
|
58
58
|
function generateKubeconfig(clusterName, clusterEndpoint, certData, opts) {
|
|
59
59
|
let args = ["eks", "get-token", "--cluster-name", clusterName];
|
|
60
|
-
const env = [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
const env = [
|
|
61
|
+
{
|
|
62
|
+
name: "KUBERNETES_EXEC_INFO",
|
|
63
|
+
value: `{"apiVersion": "client.authentication.k8s.io/v1beta1"}`,
|
|
64
|
+
},
|
|
65
|
+
];
|
|
64
66
|
if (opts === null || opts === void 0 ? void 0 : opts.roleArn) {
|
|
65
67
|
args = [...args, "--role", opts.roleArn];
|
|
66
68
|
}
|
|
67
69
|
if (opts === null || opts === void 0 ? void 0 : opts.profileName) {
|
|
68
70
|
env.push({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
name: "AWS_PROFILE",
|
|
72
|
+
value: opts.profileName,
|
|
71
73
|
});
|
|
72
74
|
}
|
|
73
|
-
return pulumi.all([
|
|
74
|
-
args,
|
|
75
|
-
env,
|
|
76
|
-
]).apply(([tokenArgs, envvars]) => {
|
|
75
|
+
return pulumi.all([args, env]).apply(([tokenArgs, envvars]) => {
|
|
77
76
|
return {
|
|
78
77
|
apiVersion: "v1",
|
|
79
|
-
clusters: [
|
|
78
|
+
clusters: [
|
|
79
|
+
{
|
|
80
80
|
cluster: {
|
|
81
81
|
server: clusterEndpoint,
|
|
82
82
|
"certificate-authority-data": certData,
|
|
83
83
|
},
|
|
84
84
|
name: "kubernetes",
|
|
85
|
-
}
|
|
86
|
-
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
contexts: [
|
|
88
|
+
{
|
|
87
89
|
context: {
|
|
88
90
|
cluster: "kubernetes",
|
|
89
91
|
user: "aws",
|
|
90
92
|
},
|
|
91
93
|
name: "aws",
|
|
92
|
-
}
|
|
94
|
+
},
|
|
95
|
+
],
|
|
93
96
|
"current-context": "aws",
|
|
94
97
|
kind: "Config",
|
|
95
|
-
users: [
|
|
98
|
+
users: [
|
|
99
|
+
{
|
|
96
100
|
name: "aws",
|
|
97
101
|
user: {
|
|
98
102
|
exec: {
|
|
@@ -102,7 +106,8 @@ function generateKubeconfig(clusterName, clusterEndpoint, certData, opts) {
|
|
|
102
106
|
env: envvars,
|
|
103
107
|
},
|
|
104
108
|
},
|
|
105
|
-
}
|
|
109
|
+
},
|
|
110
|
+
],
|
|
106
111
|
};
|
|
107
112
|
});
|
|
108
113
|
}
|
|
@@ -182,7 +187,7 @@ function getRoleProvider(name, region, profile, parent, provider) {
|
|
|
182
187
|
roleArn: iamRole.arn.apply((arn) => __awaiter(this, void 0, void 0, function* () {
|
|
183
188
|
// wait 30 seconds to assume the IAM Role https://github.com/pulumi/pulumi-aws/issues/673
|
|
184
189
|
if (!pulumi.runtime.isDryRun()) {
|
|
185
|
-
yield new Promise(resolve => setTimeout(resolve, 30 * 1000));
|
|
190
|
+
yield new Promise((resolve) => setTimeout(resolve, 30 * 1000));
|
|
186
191
|
}
|
|
187
192
|
return arn;
|
|
188
193
|
})),
|
|
@@ -210,18 +215,19 @@ function createCore(name, args, parent, provider) {
|
|
|
210
215
|
if (args.subnetIds && (args.publicSubnetIds || args.privateSubnetIds)) {
|
|
211
216
|
throw new Error("subnetIds, and the use of publicSubnetIds and/or privateSubnetIds are mutually exclusive. Choose a single approach.");
|
|
212
217
|
}
|
|
213
|
-
if (args.nodeGroupOptions &&
|
|
214
|
-
args.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
218
|
+
if (args.nodeGroupOptions &&
|
|
219
|
+
(args.nodeSubnetIds ||
|
|
220
|
+
args.nodeAssociatePublicIpAddress ||
|
|
221
|
+
args.instanceType ||
|
|
222
|
+
args.instanceProfileName ||
|
|
223
|
+
args.nodePublicKey ||
|
|
224
|
+
args.nodeRootVolumeSize ||
|
|
225
|
+
args.nodeUserData ||
|
|
226
|
+
args.minSize ||
|
|
227
|
+
args.maxSize ||
|
|
228
|
+
args.desiredCapacity ||
|
|
229
|
+
args.nodeAmiId ||
|
|
230
|
+
args.gpu)) {
|
|
225
231
|
throw new Error("Setting nodeGroupOptions, and any set of singular node group option(s) on the cluster, is mutually exclusive. Choose a single approach.");
|
|
226
232
|
}
|
|
227
233
|
// Configure the node group options.
|
|
@@ -240,7 +246,7 @@ function createCore(name, args, parent, provider) {
|
|
|
240
246
|
gpu: args.gpu,
|
|
241
247
|
version: args.version,
|
|
242
248
|
};
|
|
243
|
-
const partition = pulumi.output(aws.getPartition({ provider }))
|
|
249
|
+
const { partition, dnsSuffix } = pulumi.output(aws.getPartition({ provider }));
|
|
244
250
|
// Configure default networking architecture.
|
|
245
251
|
let vpcId = args.vpcId;
|
|
246
252
|
let clusterSubnetIds = [];
|
|
@@ -248,8 +254,10 @@ function createCore(name, args, parent, provider) {
|
|
|
248
254
|
if (!args.vpcId) {
|
|
249
255
|
const invokeOpts = { parent, async: true };
|
|
250
256
|
const vpc = aws.ec2.getVpc({ default: true }, invokeOpts);
|
|
251
|
-
vpcId = vpc.then(v => v.id);
|
|
252
|
-
clusterSubnetIds = vpc
|
|
257
|
+
vpcId = vpc.then((v) => v.id);
|
|
258
|
+
clusterSubnetIds = vpc
|
|
259
|
+
.then((v) => aws.ec2.getSubnets({ filters: [{ name: "vpc-id", values: [v.id] }] }, invokeOpts))
|
|
260
|
+
.then((subnets) => subnets.ids);
|
|
253
261
|
}
|
|
254
262
|
// Form the subnetIds to use on the cluster from either:
|
|
255
263
|
// - subnetIds
|
|
@@ -258,10 +266,9 @@ function createCore(name, args, parent, provider) {
|
|
|
258
266
|
clusterSubnetIds = args.subnetIds;
|
|
259
267
|
}
|
|
260
268
|
else if (args.publicSubnetIds !== undefined || args.privateSubnetIds !== undefined) {
|
|
261
|
-
clusterSubnetIds = pulumi
|
|
262
|
-
args.publicSubnetIds || [],
|
|
263
|
-
|
|
264
|
-
]).apply(([publicIds, privateIds]) => {
|
|
269
|
+
clusterSubnetIds = pulumi
|
|
270
|
+
.all([args.publicSubnetIds || [], args.privateSubnetIds || []])
|
|
271
|
+
.apply(([publicIds, privateIds]) => {
|
|
265
272
|
return [...publicIds, ...privateIds];
|
|
266
273
|
});
|
|
267
274
|
}
|
|
@@ -271,7 +278,7 @@ function createCore(name, args, parent, provider) {
|
|
|
271
278
|
eksRole = pulumi.output(args.serviceRole);
|
|
272
279
|
}
|
|
273
280
|
else {
|
|
274
|
-
eksRole =
|
|
281
|
+
eksRole = new servicerole_1.ServiceRole(`${name}-eksRole`, {
|
|
275
282
|
service: "eks.amazonaws.com",
|
|
276
283
|
description: "Allows EKS to manage clusters on your behalf.",
|
|
277
284
|
managedPolicyArns: [
|
|
@@ -280,7 +287,7 @@ function createCore(name, args, parent, provider) {
|
|
|
280
287
|
arn: pulumi.interpolate `arn:${partition}:iam::aws:policy/AmazonEKSClusterPolicy`,
|
|
281
288
|
},
|
|
282
289
|
],
|
|
283
|
-
}, { parent, provider })
|
|
290
|
+
}, { parent, provider }).role;
|
|
284
291
|
}
|
|
285
292
|
// Create the EKS cluster security group
|
|
286
293
|
let eksClusterSecurityGroup;
|
|
@@ -291,10 +298,7 @@ function createCore(name, args, parent, provider) {
|
|
|
291
298
|
eksClusterSecurityGroup = new aws.ec2.SecurityGroup(`${name}-eksClusterSecurityGroup`, {
|
|
292
299
|
vpcId: vpcId,
|
|
293
300
|
revokeRulesOnDelete: true,
|
|
294
|
-
tags: pulumi.all([
|
|
295
|
-
args.tags,
|
|
296
|
-
args.clusterSecurityGroupTags,
|
|
297
|
-
]).apply(([tags, clusterSecurityGroupTags]) => (Object.assign(Object.assign({ "Name": `${name}-eksClusterSecurityGroup` }, clusterSecurityGroupTags), tags))),
|
|
301
|
+
tags: pulumi.all([args.tags, args.clusterSecurityGroupTags]).apply(([tags, clusterSecurityGroupTags]) => (Object.assign(Object.assign({ Name: `${name}-eksClusterSecurityGroup` }, clusterSecurityGroupTags), tags))),
|
|
298
302
|
}, { parent, provider });
|
|
299
303
|
const eksClusterInternetEgressRule = new aws.ec2.SecurityGroupRule(`${name}-eksClusterInternetEgressRule`, {
|
|
300
304
|
description: "Allow internet access.",
|
|
@@ -311,20 +315,24 @@ function createCore(name, args, parent, provider) {
|
|
|
311
315
|
let encryptionProvider;
|
|
312
316
|
let encryptionConfig;
|
|
313
317
|
if (args.encryptionConfigKeyArn) {
|
|
314
|
-
encryptionProvider = pulumi.output(args.encryptionConfigKeyArn).apply(keyArn => ({
|
|
315
|
-
|
|
318
|
+
encryptionProvider = pulumi.output(args.encryptionConfigKeyArn).apply((keyArn) => ({
|
|
319
|
+
keyArn,
|
|
320
|
+
}));
|
|
321
|
+
encryptionConfig = encryptionProvider.apply((ep) => ({
|
|
316
322
|
provider: ep,
|
|
317
323
|
resources: ["secrets"],
|
|
318
324
|
}));
|
|
319
325
|
}
|
|
320
326
|
let kubernetesNetworkConfig;
|
|
321
327
|
if (args.kubernetesServiceIpAddressRange) {
|
|
322
|
-
kubernetesNetworkConfig = pulumi
|
|
328
|
+
kubernetesNetworkConfig = pulumi
|
|
329
|
+
.output(args.kubernetesServiceIpAddressRange)
|
|
330
|
+
.apply((serviceIpv4Cidr) => ({ serviceIpv4Cidr }));
|
|
323
331
|
}
|
|
324
332
|
// Create the EKS cluster
|
|
325
333
|
const eksCluster = new aws.eks.Cluster(`${name}-eksCluster`, {
|
|
326
334
|
name: args.name,
|
|
327
|
-
roleArn: eksRole.apply(r => r.arn),
|
|
335
|
+
roleArn: eksRole.apply((r) => r.arn),
|
|
328
336
|
vpcConfig: {
|
|
329
337
|
securityGroupIds: [eksClusterSecurityGroup.id],
|
|
330
338
|
subnetIds: clusterSubnetIds,
|
|
@@ -335,10 +343,7 @@ function createCore(name, args, parent, provider) {
|
|
|
335
343
|
version: args.version,
|
|
336
344
|
enabledClusterLogTypes: args.enabledClusterLogTypes,
|
|
337
345
|
defaultAddonsToRemoves: args.defaultAddonsToRemove,
|
|
338
|
-
tags: pulumi.all([
|
|
339
|
-
args.tags,
|
|
340
|
-
args.clusterTags,
|
|
341
|
-
]).apply(([tags, clusterTags]) => (Object.assign(Object.assign({ "Name": `${name}-eksCluster` }, clusterTags), tags))),
|
|
346
|
+
tags: pulumi.all([args.tags, args.clusterTags]).apply(([tags, clusterTags]) => (Object.assign(Object.assign({ Name: `${name}-eksCluster` }, clusterTags), tags))),
|
|
342
347
|
encryptionConfig,
|
|
343
348
|
kubernetesNetworkConfig,
|
|
344
349
|
}, {
|
|
@@ -364,8 +369,7 @@ function createCore(name, args, parent, provider) {
|
|
|
364
369
|
try {
|
|
365
370
|
yield new Promise((resolve, reject) => {
|
|
366
371
|
const options = Object.assign(Object.assign({}, url.parse(healthz)), { rejectUnauthorized: false, agent: agent, timeout: reqTimeoutMilliseconds });
|
|
367
|
-
const req = https
|
|
368
|
-
.request(options, res => {
|
|
372
|
+
const req = https.request(options, (res) => {
|
|
369
373
|
res.statusCode === 200 ? resolve() : reject(); // Verify healthz returns 200
|
|
370
374
|
});
|
|
371
375
|
req.on("timeout", reject);
|
|
@@ -376,10 +380,10 @@ function createCore(name, args, parent, provider) {
|
|
|
376
380
|
break;
|
|
377
381
|
}
|
|
378
382
|
catch (e) {
|
|
379
|
-
const retrySecondsLeft = (maxRetries - i) * timeoutMilliseconds / 1000;
|
|
383
|
+
const retrySecondsLeft = ((maxRetries - i) * timeoutMilliseconds) / 1000;
|
|
380
384
|
pulumi.log.info(`Waiting up to (${retrySecondsLeft}) more seconds for cluster readiness...`, eksCluster, undefined, true);
|
|
381
385
|
}
|
|
382
|
-
yield new Promise(resolve => setTimeout(resolve, timeoutMilliseconds));
|
|
386
|
+
yield new Promise((resolve) => setTimeout(resolve, timeoutMilliseconds));
|
|
383
387
|
}
|
|
384
388
|
}
|
|
385
389
|
return clusterEndpoint;
|
|
@@ -387,11 +391,17 @@ function createCore(name, args, parent, provider) {
|
|
|
387
391
|
// Compute the required kubeconfig. Note that we do not export this value: we want the exported config to
|
|
388
392
|
// depend on the autoscaling group we'll create later so that nothing attempts to use the EKS cluster before
|
|
389
393
|
// its worker nodes have come up.
|
|
390
|
-
const kubeconfig = pulumi
|
|
391
|
-
.
|
|
394
|
+
const kubeconfig = pulumi
|
|
395
|
+
.all([
|
|
396
|
+
eksCluster.name,
|
|
397
|
+
endpoint,
|
|
398
|
+
eksCluster.certificateAuthority,
|
|
399
|
+
args.providerCredentialOpts,
|
|
400
|
+
])
|
|
401
|
+
.apply(([clusterName, clusterEndpoint, clusterCertificateAuthority, providerCredentialOpts,]) => {
|
|
392
402
|
let config = {};
|
|
393
403
|
if (args.creationRoleProvider) {
|
|
394
|
-
config = args.creationRoleProvider.role.arn.apply(arn => {
|
|
404
|
+
config = args.creationRoleProvider.role.arn.apply((arn) => {
|
|
395
405
|
const opts = { roleArn: arn };
|
|
396
406
|
return generateKubeconfig(clusterName, clusterEndpoint, clusterCertificateAuthority.data, opts);
|
|
397
407
|
});
|
|
@@ -435,7 +445,9 @@ function createCore(name, args, parent, provider) {
|
|
|
435
445
|
let instanceRoles;
|
|
436
446
|
// Create role mappings of the instance roles specified for aws-auth.
|
|
437
447
|
if (args.instanceRoles) {
|
|
438
|
-
instanceRoleMappings = pulumi
|
|
448
|
+
instanceRoleMappings = pulumi
|
|
449
|
+
.output(args.instanceRoles)
|
|
450
|
+
.apply((roles) => roles.map((role) => createInstanceRoleMapping(role.arn)));
|
|
439
451
|
instanceRoles = pulumi.output(args.instanceRoles);
|
|
440
452
|
}
|
|
441
453
|
else if (args.instanceRole) {
|
|
@@ -443,12 +455,14 @@ function createCore(name, args, parent, provider) {
|
|
|
443
455
|
if (!skipDefaultNodeGroup) {
|
|
444
456
|
nodeGroupOptions.instanceProfile = createOrGetInstanceProfile(name, parent, args.instanceRole, args.instanceProfileName);
|
|
445
457
|
}
|
|
446
|
-
instanceRoleMappings = pulumi
|
|
458
|
+
instanceRoleMappings = pulumi
|
|
459
|
+
.output(args.instanceRole)
|
|
460
|
+
.apply((instanceRole) => [createInstanceRoleMapping(instanceRole.arn)]);
|
|
447
461
|
instanceRoles = pulumi.output([args.instanceRole]);
|
|
448
462
|
}
|
|
449
463
|
else {
|
|
450
|
-
const instanceRole =
|
|
451
|
-
service:
|
|
464
|
+
const instanceRole = new servicerole_1.ServiceRole(`${name}-instanceRole`, {
|
|
465
|
+
service: pulumi.interpolate `ec2.${dnsSuffix}`,
|
|
452
466
|
managedPolicyArns: [
|
|
453
467
|
{
|
|
454
468
|
id: "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
|
|
@@ -463,7 +477,7 @@ function createCore(name, args, parent, provider) {
|
|
|
463
477
|
arn: pulumi.interpolate `arn:${partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly`,
|
|
464
478
|
},
|
|
465
479
|
],
|
|
466
|
-
}, { parent, provider })
|
|
480
|
+
}, { parent, provider }).role;
|
|
467
481
|
instanceRoles = pulumi.output([instanceRole]);
|
|
468
482
|
// Create a new policy for the role, if specified.
|
|
469
483
|
if (args.customInstanceRolePolicy) {
|
|
@@ -477,13 +491,16 @@ function createCore(name, args, parent, provider) {
|
|
|
477
491
|
if (!skipDefaultNodeGroup) {
|
|
478
492
|
nodeGroupOptions.instanceProfile = createOrGetInstanceProfile(name, parent, instanceRole, args.instanceProfileName);
|
|
479
493
|
}
|
|
480
|
-
instanceRoleMappings = pulumi
|
|
494
|
+
instanceRoleMappings = pulumi
|
|
495
|
+
.output(instanceRole)
|
|
496
|
+
.apply((role) => [createInstanceRoleMapping(role.arn)]);
|
|
481
497
|
}
|
|
482
|
-
const roleMappings = pulumi
|
|
498
|
+
const roleMappings = pulumi
|
|
499
|
+
.all([pulumi.output(args.roleMappings || []), instanceRoleMappings])
|
|
483
500
|
.apply(([mappings, instanceMappings]) => {
|
|
484
501
|
let mappingYaml = "";
|
|
485
502
|
try {
|
|
486
|
-
mappingYaml = jsyaml.
|
|
503
|
+
mappingYaml = jsyaml.dump([...mappings, ...instanceMappings].map((m) => ({
|
|
487
504
|
rolearn: m.roleArn,
|
|
488
505
|
username: m.username,
|
|
489
506
|
groups: m.groups,
|
|
@@ -498,10 +515,10 @@ function createCore(name, args, parent, provider) {
|
|
|
498
515
|
mapRoles: roleMappings,
|
|
499
516
|
};
|
|
500
517
|
if (args.userMappings) {
|
|
501
|
-
nodeAccessData.mapUsers = pulumi.output(args.userMappings).apply(mappings => {
|
|
518
|
+
nodeAccessData.mapUsers = pulumi.output(args.userMappings).apply((mappings) => {
|
|
502
519
|
let mappingYaml = "";
|
|
503
520
|
try {
|
|
504
|
-
mappingYaml = jsyaml.
|
|
521
|
+
mappingYaml = jsyaml.dump(mappings.map((m) => ({
|
|
505
522
|
userarn: m.userArn,
|
|
506
523
|
username: m.username,
|
|
507
524
|
groups: m.groups,
|
|
@@ -521,19 +538,22 @@ function createCore(name, args, parent, provider) {
|
|
|
521
538
|
},
|
|
522
539
|
data: nodeAccessData,
|
|
523
540
|
}, { parent, provider: k8sProvider });
|
|
524
|
-
const fargateProfile = pulumi
|
|
541
|
+
const fargateProfile = pulumi
|
|
542
|
+
.output(args.fargate)
|
|
543
|
+
.apply((argsFargate) => {
|
|
525
544
|
let result;
|
|
526
545
|
if (argsFargate) {
|
|
527
546
|
const fargate = argsFargate !== true ? argsFargate : {};
|
|
528
|
-
const podExecutionRoleArn = fargate.podExecutionRoleArn ||
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
547
|
+
const podExecutionRoleArn = fargate.podExecutionRoleArn ||
|
|
548
|
+
new servicerole_1.ServiceRole(`${name}-podExecutionRole`, {
|
|
549
|
+
service: "eks-fargate-pods.amazonaws.com",
|
|
550
|
+
managedPolicyArns: [
|
|
551
|
+
{
|
|
552
|
+
id: "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy",
|
|
553
|
+
arn: pulumi.interpolate `arn:${partition}:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy`,
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
}, { parent, provider }).role.apply((r) => r.arn);
|
|
537
557
|
const selectors = fargate.selectors || [
|
|
538
558
|
// For `fargate: true`, default to including the `default` namespaces and
|
|
539
559
|
// `kube-system` namespaces so that all pods by default run in Fargate.
|
|
@@ -555,28 +575,32 @@ function createCore(name, args, parent, provider) {
|
|
|
555
575
|
clusterName: eksCluster.name,
|
|
556
576
|
podExecutionRoleArn: podExecutionRoleArn,
|
|
557
577
|
selectors: selectors,
|
|
558
|
-
subnetIds: pulumi
|
|
578
|
+
subnetIds: pulumi
|
|
579
|
+
.output(clusterSubnetIds)
|
|
580
|
+
.apply((subnets) => nodegroup_1.computeWorkerSubnets(parent, subnets)),
|
|
559
581
|
}, { parent, dependsOn: [eksNodeAccess], provider });
|
|
560
582
|
// Once the FargateProfile has been created, try to patch CoreDNS if needed. See
|
|
561
583
|
// https://docs.aws.amazon.com/eks/latest/userguide/fargate-getting-started.html#fargate-gs-coredns.
|
|
562
584
|
pulumi.all([result.id, selectors, kubeconfig]).apply(([_, sels, kconfig]) => {
|
|
563
585
|
// Only patch CoreDNS if there is a selector in the FargateProfile which causes
|
|
564
586
|
// `kube-system` pods to launch in Fargate.
|
|
565
|
-
if (sels.findIndex(s => s.namespace === "kube-system") !== -1) {
|
|
587
|
+
if (sels.findIndex((s) => s.namespace === "kube-system") !== -1) {
|
|
566
588
|
// Only do the imperative patching during deployments, not previews.
|
|
567
589
|
if (!pulumi.runtime.isDryRun()) {
|
|
568
590
|
// Write the kubeconfig to a tmp file and use it to patch the `coredns`
|
|
569
591
|
// deployment that AWS deployed already as part of cluster creation.
|
|
570
592
|
const tmpKubeconfig = tmp.fileSync();
|
|
571
593
|
fs.writeFileSync(tmpKubeconfig.fd, JSON.stringify(kconfig));
|
|
572
|
-
const patch = [
|
|
594
|
+
const patch = [
|
|
595
|
+
{
|
|
573
596
|
op: "replace",
|
|
574
597
|
path: "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type",
|
|
575
598
|
value: "fargate",
|
|
576
|
-
}
|
|
599
|
+
},
|
|
600
|
+
];
|
|
577
601
|
const cmd = `kubectl patch deployment coredns -n kube-system --type json -p='${JSON.stringify(patch)}'`;
|
|
578
602
|
childProcess.execSync(cmd, {
|
|
579
|
-
env: Object.assign(Object.assign({}, process.env), {
|
|
603
|
+
env: Object.assign(Object.assign({}, process.env), { KUBECONFIG: tmpKubeconfig.name }),
|
|
580
604
|
});
|
|
581
605
|
}
|
|
582
606
|
}
|
|
@@ -646,8 +670,11 @@ function createHttpAgent(proxy) {
|
|
|
646
670
|
// Note: Envars used are a convention that were based on:
|
|
647
671
|
// - curl: https://curl.haxx.se/docs/manual.html
|
|
648
672
|
// - wget: https://www.gnu.org/software/wget/manual/html_node/Proxies.html
|
|
649
|
-
proxy =
|
|
650
|
-
process.env.
|
|
673
|
+
proxy =
|
|
674
|
+
process.env.HTTPS_PROXY ||
|
|
675
|
+
process.env.https_proxy ||
|
|
676
|
+
process.env.HTTP_PROXY ||
|
|
677
|
+
process.env.http_proxy;
|
|
651
678
|
}
|
|
652
679
|
if (proxy) {
|
|
653
680
|
/**
|
|
@@ -769,10 +796,7 @@ function createCluster(name, self, args, opts) {
|
|
|
769
796
|
vpcId: core.vpcId,
|
|
770
797
|
clusterSecurityGroup: core.clusterSecurityGroup,
|
|
771
798
|
eksCluster: core.cluster,
|
|
772
|
-
tags: pulumi.all([
|
|
773
|
-
args.tags,
|
|
774
|
-
args.nodeSecurityGroupTags,
|
|
775
|
-
]).apply(([tags, nodeSecurityGroupTags]) => (Object.assign(Object.assign({}, nodeSecurityGroupTags), tags))),
|
|
799
|
+
tags: pulumi.all([args.tags, args.nodeSecurityGroupTags]).apply(([tags, nodeSecurityGroupTags]) => (Object.assign(Object.assign({}, nodeSecurityGroupTags), tags))),
|
|
776
800
|
}, self);
|
|
777
801
|
core.nodeGroupOptions.nodeSecurityGroup = nodeSecurityGroup;
|
|
778
802
|
core.nodeGroupOptions.clusterIngressRule = eksClusterIngressRule;
|