From d3edef2326ef823b82063994a68ba48a698e0658 Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Thu, 3 Oct 2024 22:15:03 +0200 Subject: [PATCH] Add parameter for skipping default security groups (#1416) Pulumi EKS currently always creates a cluster security group and node security group. - The cluster security group gets assigned to the control plane ENIs in addition to the security group EKS creates (see [AWS Docs](https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html)). This security group gets an ingress rule from the node security group. - The node security group gets assigned to `NodeGroup` and `NodeGroupV2` components that do not specify a custom security group. Users that either manage the node security themselves or use the `ManagedNodeGroup` component (uses the EKS created SG) do not need those default security groups. This change adds a flag on the cluster (`skipDefaultSecurityGroups`) that will skip creating those default security groups. Instead. This introduces a small breaking change, the `clusterSecurityGroup`, `nodeSecurityGroup` and `clusterIngressRule` outputs are now optional. The impact of this should be minimal because users that create custom node groups usually do not use the security groups of the cluster for that. If they do, they need to add a null check. Fixes https://github.com/pulumi/pulumi-eks/issues/747 --- docs/eks-v3-migration.md | 6 ++ examples/examples_nodejs_test.go | 21 +++++ examples/extra-sg/index.ts | 4 +- examples/tests/migrate-nodegroups/utils.ts | 4 +- .../skip-default-security-groups/Pulumi.yaml | 3 + .../skip-default-security-groups/README.md | 3 + .../tests/skip-default-security-groups/iam.ts | 28 +++++++ .../skip-default-security-groups/index.ts | 41 +++++++++ .../skip-default-security-groups/package.json | 13 +++ .../tsconfig.json | 24 ++++++ nodejs/eks/cluster.ts | 83 ++++++++++++------- nodejs/eks/nodegroup.ts | 34 ++++---- nodejs/eks/securitygroup.ts | 24 ++++-- provider/cmd/pulumi-gen-eks/main.go | 13 ++- .../nodejs-templates/clusterMixins.ts | 15 +++- provider/cmd/pulumi-resource-eks/schema.json | 9 +- sdk/dotnet/Cluster.cs | 14 +++- sdk/dotnet/Inputs/CoreDataArgs.cs | 4 +- sdk/dotnet/Outputs/CoreData.cs | 4 +- sdk/go/eks/cluster.go | 8 ++ .../src/main/java/com/pulumi/eks/Cluster.java | 18 ++-- .../main/java/com/pulumi/eks/ClusterArgs.java | 33 ++++++++ .../com/pulumi/eks/inputs/CoreDataArgs.java | 13 ++- .../java/com/pulumi/eks/outputs/CoreData.java | 14 ++-- sdk/nodejs/cluster.ts | 13 ++- sdk/nodejs/clusterMixins.ts | 15 +++- sdk/nodejs/types/input.ts | 2 +- sdk/nodejs/types/output.ts | 2 +- sdk/python/pulumi_eks/_inputs.py | 39 ++++----- sdk/python/pulumi_eks/cluster.py | 32 ++++++- sdk/python/pulumi_eks/outputs.py | 19 +++-- 31 files changed, 418 insertions(+), 137 deletions(-) create mode 100644 examples/tests/skip-default-security-groups/Pulumi.yaml create mode 100755 examples/tests/skip-default-security-groups/README.md create mode 100644 examples/tests/skip-default-security-groups/iam.ts create mode 100644 examples/tests/skip-default-security-groups/index.ts create mode 100644 examples/tests/skip-default-security-groups/package.json create mode 100644 examples/tests/skip-default-security-groups/tsconfig.json diff --git a/docs/eks-v3-migration.md b/docs/eks-v3-migration.md index 9c4f4307c..270df96a0 100644 --- a/docs/eks-v3-migration.md +++ b/docs/eks-v3-migration.md @@ -160,3 +160,9 @@ The `NodeGroup` and `NodeGroupV2` components now accept inputs for the following - `nodeAssociatePublicIpAddress` If you're using Go you'll need to adjust your program to handle those types being inputs. + +### Default Security Groups can now be disabled +If you do not need the default cluster and node security groups you can disable those now +with the `skipDefaultSecurityGroups` flag. Those security groups will not be created when setting that flag to true. + +Because of this change, the `clusterSecurityGroup`, `nodeSecurityGroup` and `clusterIngressRule` properties are optional now. If you're using those outputs you'll need to update your code accordingly. diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index e70289471..5160e2e0b 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -1001,3 +1001,24 @@ func TestAccClusterAddons(t *testing.T) { programTestWithExtraOptions(t, &test, nil) } + +func TestAccSkipDefaultSecurityGroups(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + test := getJSBaseOptions(t). + With(integration.ProgramTestOptions{ + Dir: path.Join(getCwd(t), "tests", "skip-default-security-groups"), + ExtraRuntimeValidation: func(t *testing.T, info integration.RuntimeValidationStackInfo) { + utils.RunEKSSmokeTest(t, + info.Deployment.Resources, + info.Outputs["kubeconfig"], + ) + + assert.Nil(t, info.Outputs["clusterSecurityGroup"]) + assert.Nil(t, info.Outputs["nodeSecurityGroup"]) + }, + }) + + programTestWithExtraOptions(t, &test, nil) +} diff --git a/examples/extra-sg/index.ts b/examples/extra-sg/index.ts index 7199c72a8..4c717c40b 100644 --- a/examples/extra-sg/index.ts +++ b/examples/extra-sg/index.ts @@ -61,7 +61,7 @@ const nodeIngressRule = new aws.ec2.SecurityGroupRule("nodeIngressRule", { fromPort: 0, toPort: 65535, protocol: "tcp", - securityGroupId: cluster.nodeSecurityGroup.id, + securityGroupId: cluster.nodeSecurityGroup.apply((sg) => sg!.id), sourceSecurityGroupId: customSecurityGroup.id, }); @@ -108,6 +108,6 @@ const ng = new eks.NodeGroupV2("example-mng", { amiId: "ami-066e69f6f03b5383e", extraNodeSecurityGroups: [ customSecurityGroup, // Plain type - cluster.nodeSecurityGroup, // Input type + cluster.nodeSecurityGroup.apply(sg => sg!), // Input type ], }); diff --git a/examples/tests/migrate-nodegroups/utils.ts b/examples/tests/migrate-nodegroups/utils.ts index 11a558b31..4878830cb 100644 --- a/examples/tests/migrate-nodegroups/utils.ts +++ b/examples/tests/migrate-nodegroups/utils.ts @@ -16,8 +16,8 @@ export function createNodeGroup( ): eks.NodeGroup { return new eks.NodeGroup(name, { cluster: args.cluster, - nodeSecurityGroup: args.cluster.nodeSecurityGroup, - clusterIngressRule: args.cluster.eksClusterIngressRule, + nodeSecurityGroup: args.cluster.nodeSecurityGroup.apply(v => v!), + clusterIngressRule: args.cluster.eksClusterIngressRule.apply(v => v!), instanceType: args.instanceType, nodeAssociatePublicIpAddress: false, desiredCapacity: args.desiredCapacity, diff --git a/examples/tests/skip-default-security-groups/Pulumi.yaml b/examples/tests/skip-default-security-groups/Pulumi.yaml new file mode 100644 index 000000000..b41d444f1 --- /dev/null +++ b/examples/tests/skip-default-security-groups/Pulumi.yaml @@ -0,0 +1,3 @@ +name: skip-default-security-groups +description: EKS cluster without default security groups +runtime: nodejs diff --git a/examples/tests/skip-default-security-groups/README.md b/examples/tests/skip-default-security-groups/README.md new file mode 100755 index 000000000..9bdeedec3 --- /dev/null +++ b/examples/tests/skip-default-security-groups/README.md @@ -0,0 +1,3 @@ +# examples/tests/skip-default-security-groups + +Tests that the cluster can be created without default security groups diff --git a/examples/tests/skip-default-security-groups/iam.ts b/examples/tests/skip-default-security-groups/iam.ts new file mode 100644 index 000000000..214f5bfc0 --- /dev/null +++ b/examples/tests/skip-default-security-groups/iam.ts @@ -0,0 +1,28 @@ +import * as aws from "@pulumi/aws"; +import * as pulumi from "@pulumi/pulumi"; + +const managedPolicyArns: string[] = [ + "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy", + "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy", + "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly", + "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", +]; + +// Creates a role and attches the EKS worker node IAM managed policies +export function createRole(name: string): aws.iam.Role { + const role = new aws.iam.Role(name, { + assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ + Service: "ec2.amazonaws.com", + }), + }); + + let counter = 0; + for (const policy of managedPolicyArns) { + // Create RolePolicyAttachment without returning it. + const rpa = new aws.iam.RolePolicyAttachment(`${name}-policy-${counter++}`, + { policyArn: policy, role: role }, + ); + } + + return role; +} diff --git a/examples/tests/skip-default-security-groups/index.ts b/examples/tests/skip-default-security-groups/index.ts new file mode 100644 index 000000000..1e24825fb --- /dev/null +++ b/examples/tests/skip-default-security-groups/index.ts @@ -0,0 +1,41 @@ +import * as awsx from "@pulumi/awsx"; +import * as eks from "@pulumi/eks"; +import * as iam from "./iam"; + +// IAM roles for the node group +const role = iam.createRole("managed-ng-os"); + +// Create a new VPC +const eksVpc = new awsx.ec2.Vpc("managed-ng-os", { + enableDnsHostnames: true, + cidrBlock: "10.0.0.0/16", +}); + +// Create an EKS cluster without default security groups, those are not needed +// for managed node groups because they use the cluster security group created +// by EKS. +const cluster = new eks.Cluster("managed-ng-os", { + skipDefaultSecurityGroups: true, + vpcId: eksVpc.vpcId, + authenticationMode: eks.AuthenticationMode.API, + // Public subnets will be used for load balancers + publicSubnetIds: eksVpc.publicSubnetIds, + // Private subnets will be used for cluster nodes + privateSubnetIds: eksVpc.privateSubnetIds, +}); + +// Export the cluster's kubeconfig. +export const kubeconfig = cluster.kubeconfig; + +const managedNodeGroupAL2023 = eks.createManagedNodeGroup("al-2023-mng", { + scalingConfig: { + minSize: 1, + maxSize: 1, + desiredSize: 1, + }, + cluster: cluster, + nodeRole: role, +}); + +export const clusterSecurityGroup = cluster.clusterSecurityGroup; +export const nodeSecurityGroup = cluster.nodeSecurityGroup; diff --git a/examples/tests/skip-default-security-groups/package.json b/examples/tests/skip-default-security-groups/package.json new file mode 100644 index 000000000..4a7dee7ef --- /dev/null +++ b/examples/tests/skip-default-security-groups/package.json @@ -0,0 +1,13 @@ +{ + "name": "skip-default-security-groups", + "devDependencies": { + "@types/node": "latest", + "typescript": "^4.0.0" + }, + "dependencies": { + "@pulumi/awsx": "^2.0.0", + "@pulumi/aws": "^6.50.1", + "@pulumi/eks": "latest", + "@pulumi/pulumi": "^3.0.0" + } +} diff --git a/examples/tests/skip-default-security-groups/tsconfig.json b/examples/tests/skip-default-security-groups/tsconfig.json new file mode 100644 index 000000000..2ea71672d --- /dev/null +++ b/examples/tests/skip-default-security-groups/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "outDir": "bin", + "target": "es6", + "lib": [ + "es6" + ], + "module": "commonjs", + "moduleResolution": "node", + "declaration": true, + "sourceMap": true, + "stripInternal": true, + "experimentalDecorators": true, + "pretty": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true, + "strictNullChecks": true + }, + "files": [ + "index.ts" + ] +} diff --git a/nodejs/eks/cluster.ts b/nodejs/eks/cluster.ts index d2cc09088..a8fb0fe6f 100644 --- a/nodejs/eks/cluster.ts +++ b/nodejs/eks/cluster.ts @@ -137,7 +137,7 @@ export interface CoreData { vpcId: pulumi.Output; subnetIds: pulumi.Output; endpoint: pulumi.Output; - clusterSecurityGroup: aws.ec2.SecurityGroup; + clusterSecurityGroup?: aws.ec2.SecurityGroup; provider: k8s.Provider; instanceRoles: pulumi.Output; nodeGroupOptions: ClusterNodeGroupOptions; @@ -504,10 +504,10 @@ export function createCore( } // Create the EKS cluster security group - let eksClusterSecurityGroup: aws.ec2.SecurityGroup; + let eksClusterSecurityGroup: aws.ec2.SecurityGroup | undefined; if (args.clusterSecurityGroup) { eksClusterSecurityGroup = args.clusterSecurityGroup; - } else { + } else if (!args.skipDefaultSecurityGroups) { eksClusterSecurityGroup = new aws.ec2.SecurityGroup( `${name}-eksClusterSecurityGroup`, { @@ -581,7 +581,9 @@ export function createCore( name: args.name, roleArn: eksRole.apply((r) => r.arn), vpcConfig: { - securityGroupIds: [eksClusterSecurityGroup.id], + securityGroupIds: eksClusterSecurityGroup + ? [eksClusterSecurityGroup.id] + : undefined, subnetIds: clusterSubnetIds, endpointPrivateAccess: args.endpointPrivateAccess, endpointPublicAccess: args.endpointPublicAccess, @@ -1513,6 +1515,12 @@ export interface ClusterOptions { */ skipDefaultNodeGroup?: boolean; + /** + * If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. + * Defaults to false. + */ + skipDefaultSecurityGroups?: boolean; + /** * Whether or not to deploy the Kubernetes dashboard to the cluster. If the dashboard is deployed, it can be * accessed as follows: @@ -1877,7 +1885,7 @@ export class Cluster extends pulumi.ComponentResource { /** * The security group for the EKS cluster. */ - public readonly clusterSecurityGroup: aws.ec2.SecurityGroup; + public readonly clusterSecurityGroup: aws.ec2.SecurityGroup | undefined; /** * The service roles used by the EKS cluster. @@ -1887,12 +1895,12 @@ export class Cluster extends pulumi.ComponentResource { /** * The security group for the cluster's nodes. */ - public readonly nodeSecurityGroup: aws.ec2.SecurityGroup; + public readonly nodeSecurityGroup: aws.ec2.SecurityGroup | undefined; /** * The ingress rule that gives node group access to cluster API server */ - public readonly eksClusterIngressRule: aws.ec2.SecurityGroupRule; + public readonly eksClusterIngressRule: aws.ec2.SecurityGroupRule | undefined; /** * The default Node Group configuration, or undefined if `skipDefaultNodeGroup` was specified. @@ -1978,10 +1986,10 @@ export interface ClusterResult { kubeconfig: pulumi.Output; kubeconfigJson: pulumi.Output; awsProvider?: pulumi.ProviderResource; - clusterSecurityGroup: aws.ec2.SecurityGroup; + clusterSecurityGroup?: aws.ec2.SecurityGroup; instanceRoles: pulumi.Output; - nodeSecurityGroup: aws.ec2.SecurityGroup; - eksClusterIngressRule: aws.ec2.SecurityGroupRule; + nodeSecurityGroup?: aws.ec2.SecurityGroup; + eksClusterIngressRule?: aws.ec2.SecurityGroupRule; defaultNodeGroup: NodeGroupV2Data | undefined; eksCluster: aws.eks.Cluster; core: CoreData; @@ -2019,25 +2027,36 @@ export function createCluster( // Create the core resources required by the cluster. const core = createCore(name, args, self, opts?.provider); - // Create default node group security group and cluster ingress rule. - const [nodeSecurityGroup, eksClusterIngressRule] = createNodeGroupSecurityGroup( - name, - { - vpcId: core.vpcId, - clusterSecurityGroup: core.clusterSecurityGroup, - eksCluster: core.cluster, - tags: pulumi.all([args.tags, args.nodeSecurityGroupTags]).apply( - ([tags, nodeSecurityGroupTags]) => - { - ...nodeSecurityGroupTags, - ...tags, - }, - ), - }, - self, - ); - core.nodeGroupOptions.nodeSecurityGroup = nodeSecurityGroup; - core.nodeGroupOptions.clusterIngressRule = eksClusterIngressRule; + let nodeSecurityGroup: aws.ec2.SecurityGroup | undefined; + let eksClusterIngressRule: aws.ec2.SecurityGroupRule | undefined; + if (!args.skipDefaultSecurityGroups) { + if (!core.clusterSecurityGroup) { + throw new pulumi.ResourceError( + "clusterSecurityGroup is required when creating the default node group.", + self, + ); + } + + // Create default node group security group and cluster ingress rule. + [nodeSecurityGroup, eksClusterIngressRule] = createNodeGroupSecurityGroup( + name, + { + vpcId: core.vpcId, + clusterSecurityGroupId: core.clusterSecurityGroup.id, + eksCluster: core.cluster, + tags: pulumi.all([args.tags, args.nodeSecurityGroupTags]).apply( + ([tags, nodeSecurityGroupTags]) => + { + ...nodeSecurityGroupTags, + ...tags, + }, + ), + }, + self, + ); + core.nodeGroupOptions.nodeSecurityGroup = nodeSecurityGroup; + core.nodeGroupOptions.clusterIngressRule = eksClusterIngressRule; + } const skipDefaultNodeGroup = args.skipDefaultNodeGroup || args.fargate; @@ -2082,15 +2101,15 @@ export function createCluster( * @internal */ export class ClusterInternal extends pulumi.ComponentResource { - public readonly clusterSecurityGroup!: pulumi.Output; + public readonly clusterSecurityGroup!: pulumi.Output; public readonly core!: pulumi.Output>; public readonly defaultNodeGroup!: pulumi.Output | undefined>; public readonly eksCluster!: pulumi.Output; - public readonly eksClusterIngressRule!: pulumi.Output; + public readonly eksClusterIngressRule!: pulumi.Output; public readonly instanceRoles!: pulumi.Output; public readonly kubeconfig!: pulumi.Output; public readonly kubeconfigJson!: pulumi.Output; - public readonly nodeSecurityGroup!: pulumi.Output; + public readonly nodeSecurityGroup!: pulumi.Output; constructor(name: string, args?: ClusterOptions, opts?: pulumi.ComponentResourceOptions) { const type = "eks:index:Cluster"; diff --git a/nodejs/eks/nodegroup.ts b/nodejs/eks/nodegroup.ts index 539020283..7f8d2f506 100644 --- a/nodejs/eks/nodegroup.ts +++ b/nodejs/eks/nodegroup.ts @@ -714,7 +714,9 @@ function createNodeGroupInternal( name, { vpcId: core.vpcId, - clusterSecurityGroup: core.clusterSecurityGroup, + clusterSecurityGroupId: pulumi + .output(core.clusterSecurityGroup) + .apply((sg) => sg?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId), eksCluster: eksCluster, tags: pulumi.all([core.tags, core.nodeSecurityGroupTags]).apply( ([tags, nodeSecurityGroupTags]) => @@ -1093,19 +1095,19 @@ function createNodeGroupV2Internal( return args.instanceProfile?.arn ?? c.nodeGroupOptions.instanceProfile!.arn; }); - core.apply((c) => { - if (c.nodeGroupOptions.nodeSecurityGroup && args.nodeSecurityGroup) { - if ( - c.nodeSecurityGroupTags && - c.nodeGroupOptions.nodeSecurityGroup.id !== args.nodeSecurityGroup.id - ) { - throw new pulumi.ResourceError( - `The NodeGroup's nodeSecurityGroup and the cluster option nodeSecurityGroupTags are mutually exclusive. Choose a single approach`, - parent, - ); + const coreSecurityGroupId = core.nodeGroupOptions.nodeSecurityGroup?.apply((sg) => sg?.id); + pulumi + .all([coreSecurityGroupId, args.nodeSecurityGroup?.id, core.nodeSecurityGroupTags]) + .apply(([coreSecurityGroup, nodeSecurityGroup, sgTags]) => { + if (coreSecurityGroup && nodeSecurityGroup) { + if (sgTags && coreSecurityGroup !== nodeSecurityGroup) { + throw new pulumi.ResourceError( + `The NodeGroup's nodeSecurityGroup and the cluster option nodeSecurityGroupTags are mutually exclusive. Choose a single approach`, + parent, + ); + } } - } - }); + }); if (args.nodePublicKey && args.keyName) { throw new pulumi.ResourceError( @@ -1146,7 +1148,7 @@ function createNodeGroupV2Internal( return result; }); - let eksClusterIngressRule: aws.ec2.SecurityGroupRule = args.clusterIngressRule!; + let eksClusterIngressRule: aws.ec2.SecurityGroupRule | undefined = args.clusterIngressRule; if (args.nodeSecurityGroup) { nodeSecurityGroup = args.nodeSecurityGroup; if (eksClusterIngressRule === undefined) { @@ -1160,7 +1162,9 @@ function createNodeGroupV2Internal( name, { vpcId: core.vpcId, - clusterSecurityGroup: core.clusterSecurityGroup, + clusterSecurityGroupId: pulumi + .output(core.clusterSecurityGroup) + .apply((sg) => sg?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId), eksCluster: eksCluster, tags: core.apply( (c) => diff --git a/nodejs/eks/securitygroup.ts b/nodejs/eks/securitygroup.ts index 86e9f1cf7..60a96f258 100644 --- a/nodejs/eks/securitygroup.ts +++ b/nodejs/eks/securitygroup.ts @@ -74,9 +74,14 @@ export class NodeGroupSecurityGroup extends pulumi.ComponentResource { ) { super("eks:index:NodeGroupSecurityGroup", name, args, opts); + const { clusterSecurityGroup, ...nodeGroupSecurityArgs } = args; + [this.securityGroup, this.securityGroupRule] = createNodeGroupSecurityGroup( name, - args, + { + ...nodeGroupSecurityArgs, + clusterSecurityGroupId: pulumi.output(clusterSecurityGroup).id, + }, this, opts?.provider, ); @@ -84,6 +89,13 @@ export class NodeGroupSecurityGroup extends pulumi.ComponentResource { } } +export interface NodeGroupSecurityArgs { + vpcId: pulumi.Input; + clusterSecurityGroupId: pulumi.Input; + tags?: InputTags; + eksCluster: pulumi.Input; +} + /** * createNodeGroupSecurityGroup creates a security group for node groups with the * default ingress & egress rules required to connect and work with the EKS @@ -91,12 +103,12 @@ export class NodeGroupSecurityGroup extends pulumi.ComponentResource { */ export function createNodeGroupSecurityGroup( name: string, - args: NodeGroupSecurityGroupOptions, + args: NodeGroupSecurityArgs, parent: pulumi.ComponentResource, provider?: pulumi.ProviderResource, ): [aws.ec2.SecurityGroup, aws.ec2.SecurityGroupRule] { const eksCluster = pulumi.output(args.eksCluster); - const clusterSecurityGroup = pulumi.output(args.clusterSecurityGroup); + const clusterSecurityGroupId = pulumi.output(args.clusterSecurityGroupId); const nodeSecurityGroup = new aws.ec2.SecurityGroup( `${name}-nodeSecurityGroup`, @@ -139,7 +151,7 @@ export function createNodeGroupSecurityGroup( toPort: 65535, protocol: "tcp", securityGroupId: nodeSecurityGroup.id, - sourceSecurityGroupId: clusterSecurityGroup.id, + sourceSecurityGroupId: clusterSecurityGroupId, }, { parent, provider }, ); @@ -154,7 +166,7 @@ export function createNodeGroupSecurityGroup( toPort: 443, protocol: "tcp", securityGroupId: nodeSecurityGroup.id, - sourceSecurityGroupId: clusterSecurityGroup.id, + sourceSecurityGroupId: clusterSecurityGroupId, }, { parent, provider }, ); @@ -181,7 +193,7 @@ export function createNodeGroupSecurityGroup( fromPort: 443, toPort: 443, protocol: "tcp", - securityGroupId: clusterSecurityGroup.id, + securityGroupId: clusterSecurityGroupId, sourceSecurityGroupId: nodeSecurityGroup.id, }, { parent, provider }, diff --git a/provider/cmd/pulumi-gen-eks/main.go b/provider/cmd/pulumi-gen-eks/main.go index 7e13f8646..7dc7e4421 100644 --- a/provider/cmd/pulumi-gen-eks/main.go +++ b/provider/cmd/pulumi-gen-eks/main.go @@ -241,10 +241,7 @@ func generateSchema(version semver.Version) schema.PackageSpec { "kubeconfigJson", "awsProvider", // "provider", - "clusterSecurityGroup", "instanceRoles", - "nodeSecurityGroup", - "eksClusterIngressRule", "eksCluster", "core", }, @@ -507,6 +504,15 @@ func generateSchema(version semver.Version) schema.PackageSpec { Description: "If this toggle is set to true, the EKS cluster will be created without node " + "group attached. Defaults to false, unless `fargate` input is provided.", }, + "skipDefaultSecurityGroups": { + TypeSpec: schema.TypeSpec{ + Type: "boolean", + Plain: true, + }, + Description: "If this toggle is set to true, the EKS cluster will be created without the default " + + "node and cluster security groups. Defaults to false.\n\n" + + "See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html", + }, "tags": { TypeSpec: schema.TypeSpec{ Type: "object", @@ -1281,7 +1287,6 @@ func generateSchema(version semver.Version) schema.PackageSpec { "vpcId", "subnetIds", "endpoint", - "clusterSecurityGroup", "provider", "instanceRoles", "nodeGroupOptions", diff --git a/provider/cmd/pulumi-gen-eks/nodejs-templates/clusterMixins.ts b/provider/cmd/pulumi-gen-eks/nodejs-templates/clusterMixins.ts index b0907295d..bee5243d7 100644 --- a/provider/cmd/pulumi-gen-eks/nodejs-templates/clusterMixins.ts +++ b/provider/cmd/pulumi-gen-eks/nodejs-templates/clusterMixins.ts @@ -74,14 +74,25 @@ Object.defineProperty(Cluster.prototype, 'provider', { }) Cluster.prototype.createNodeGroup = function(name: string, args: ClusterNodeGroupOptionsArgs, awsProvider?: pulumi.ProviderResource): NodeGroup { + const { nodeSecurityGroup, clusterIngressRule } = pulumi.all([this.nodeSecurityGroup, this.eksClusterIngressRule]) + .apply(([nodeSecurityGroup, clusterIngressRule]) => { + if (!nodeSecurityGroup || !clusterIngressRule) { + throw new pulumi.ResourceError( + "The nodeSecurityGroup and eksClusterIngressRule are required when using `createNodeGroup`. Please create the cluster without specifying `skipDefaultNodeGroups`.", + this, + ); + } + + return { nodeSecurityGroup, clusterIngressRule }; + }); return new NodeGroup( name, { ...args, cluster: this.core, - nodeSecurityGroup: this.nodeSecurityGroup, - clusterIngressRule: this.eksClusterIngressRule, + nodeSecurityGroup, + clusterIngressRule, }, { // parent: this, diff --git a/provider/cmd/pulumi-resource-eks/schema.json b/provider/cmd/pulumi-resource-eks/schema.json index 5d4f16164..3d3abc314 100644 --- a/provider/cmd/pulumi-resource-eks/schema.json +++ b/provider/cmd/pulumi-resource-eks/schema.json @@ -530,7 +530,6 @@ "vpcId", "subnetIds", "endpoint", - "clusterSecurityGroup", "provider", "instanceRoles", "nodeGroupOptions", @@ -1122,10 +1121,7 @@ "kubeconfig", "kubeconfigJson", "awsProvider", - "clusterSecurityGroup", "instanceRoles", - "nodeSecurityGroup", - "eksClusterIngressRule", "eksCluster", "core" ], @@ -1360,6 +1356,11 @@ "plain": true, "description": "If this toggle is set to true, the EKS cluster will be created without node group attached. Defaults to false, unless `fargate` input is provided." }, + "skipDefaultSecurityGroups": { + "type": "boolean", + "plain": true, + "description": "If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false.\n\nSee for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html" + }, "storageClasses": { "oneOf": [ { diff --git a/sdk/dotnet/Cluster.cs b/sdk/dotnet/Cluster.cs index a36dcae61..f6cacb486 100644 --- a/sdk/dotnet/Cluster.cs +++ b/sdk/dotnet/Cluster.cs @@ -51,7 +51,7 @@ public partial class Cluster : global::Pulumi.ComponentResource /// The security group for the EKS cluster. /// [Output("clusterSecurityGroup")] - public Output ClusterSecurityGroup { get; private set; } = null!; + public Output ClusterSecurityGroup { get; private set; } = null!; /// /// The EKS cluster and its dependencies. @@ -75,7 +75,7 @@ public partial class Cluster : global::Pulumi.ComponentResource /// The ingress rule that gives node group access to cluster API server. /// [Output("eksClusterIngressRule")] - public Output EksClusterIngressRule { get; private set; } = null!; + public Output EksClusterIngressRule { get; private set; } = null!; /// /// The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. @@ -99,7 +99,7 @@ public partial class Cluster : global::Pulumi.ComponentResource /// The security group for the cluster's nodes. /// [Output("nodeSecurityGroup")] - public Output NodeSecurityGroup { get; private set; } = null!; + public Output NodeSecurityGroup { get; private set; } = null!; /// @@ -592,6 +592,14 @@ public InputList RoleMappings [Input("skipDefaultNodeGroup")] public bool? SkipDefaultNodeGroup { get; set; } + /// + /// If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + /// + /// See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + /// + [Input("skipDefaultSecurityGroups")] + public bool? SkipDefaultSecurityGroups { get; set; } + /// /// An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. /// diff --git a/sdk/dotnet/Inputs/CoreDataArgs.cs b/sdk/dotnet/Inputs/CoreDataArgs.cs index 3560f32a1..5807878bc 100644 --- a/sdk/dotnet/Inputs/CoreDataArgs.cs +++ b/sdk/dotnet/Inputs/CoreDataArgs.cs @@ -39,8 +39,8 @@ public InputList AccessEntries [Input("clusterIamRole", required: true)] public Input ClusterIamRole { get; set; } = null!; - [Input("clusterSecurityGroup", required: true)] - public Input ClusterSecurityGroup { get; set; } = null!; + [Input("clusterSecurityGroup")] + public Input? ClusterSecurityGroup { get; set; } [Input("eksNodeAccess")] public Input? EksNodeAccess { get; set; } diff --git a/sdk/dotnet/Outputs/CoreData.cs b/sdk/dotnet/Outputs/CoreData.cs index df9a6e57c..385388aa7 100644 --- a/sdk/dotnet/Outputs/CoreData.cs +++ b/sdk/dotnet/Outputs/CoreData.cs @@ -26,7 +26,7 @@ public sealed class CoreData /// The IAM Role attached to the EKS Cluster /// public readonly Pulumi.Aws.Iam.Role ClusterIamRole; - public readonly Pulumi.Aws.Ec2.SecurityGroup ClusterSecurityGroup; + public readonly Pulumi.Aws.Ec2.SecurityGroup? ClusterSecurityGroup; public readonly Pulumi.Kubernetes.Core.V1.ConfigMap? EksNodeAccess; public readonly Pulumi.Aws.Eks.Outputs.ClusterEncryptionConfig? EncryptionConfig; /// @@ -94,7 +94,7 @@ private CoreData( Pulumi.Aws.Iam.Role clusterIamRole, - Pulumi.Aws.Ec2.SecurityGroup clusterSecurityGroup, + Pulumi.Aws.Ec2.SecurityGroup? clusterSecurityGroup, Pulumi.Kubernetes.Core.V1.ConfigMap? eksNodeAccess, diff --git a/sdk/go/eks/cluster.go b/sdk/go/eks/cluster.go index 35050552c..559403712 100644 --- a/sdk/go/eks/cluster.go +++ b/sdk/go/eks/cluster.go @@ -300,6 +300,10 @@ type clusterArgs struct { ServiceRole *iam.Role `pulumi:"serviceRole"` // If this toggle is set to true, the EKS cluster will be created without node group attached. Defaults to false, unless `fargate` input is provided. SkipDefaultNodeGroup *bool `pulumi:"skipDefaultNodeGroup"` + // If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + // + // See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + SkipDefaultSecurityGroups *bool `pulumi:"skipDefaultSecurityGroups"` // An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. // // Note: As of Kubernetes v1.11+ on EKS, a default `gp2` storage class will always be created automatically for the cluster by the EKS service. See https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html @@ -532,6 +536,10 @@ type ClusterArgs struct { ServiceRole iam.RoleInput // If this toggle is set to true, the EKS cluster will be created without node group attached. Defaults to false, unless `fargate` input is provided. SkipDefaultNodeGroup *bool + // If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + // + // See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + SkipDefaultSecurityGroups *bool // An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. // // Note: As of Kubernetes v1.11+ on EKS, a default `gp2` storage class will always be created automatically for the cluster by the EKS service. See https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html diff --git a/sdk/java/src/main/java/com/pulumi/eks/Cluster.java b/sdk/java/src/main/java/com/pulumi/eks/Cluster.java index 3fd81ce0b..de4b821f7 100644 --- a/sdk/java/src/main/java/com/pulumi/eks/Cluster.java +++ b/sdk/java/src/main/java/com/pulumi/eks/Cluster.java @@ -82,14 +82,14 @@ public Output awsProvider() { * */ @Export(name="clusterSecurityGroup", refs={SecurityGroup.class}, tree="[0]") - private Output clusterSecurityGroup; + private Output clusterSecurityGroup; /** * @return The security group for the EKS cluster. * */ - public Output clusterSecurityGroup() { - return this.clusterSecurityGroup; + public Output> clusterSecurityGroup() { + return Codegen.optional(this.clusterSecurityGroup); } /** * The EKS cluster and its dependencies. @@ -138,14 +138,14 @@ public Output eksCluster() { * */ @Export(name="eksClusterIngressRule", refs={SecurityGroupRule.class}, tree="[0]") - private Output eksClusterIngressRule; + private Output eksClusterIngressRule; /** * @return The ingress rule that gives node group access to cluster API server. * */ - public Output eksClusterIngressRule() { - return this.eksClusterIngressRule; + public Output> eksClusterIngressRule() { + return Codegen.optional(this.eksClusterIngressRule); } /** * The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. @@ -194,14 +194,14 @@ public Output kubeconfigJson() { * */ @Export(name="nodeSecurityGroup", refs={SecurityGroup.class}, tree="[0]") - private Output nodeSecurityGroup; + private Output nodeSecurityGroup; /** * @return The security group for the cluster's nodes. * */ - public Output nodeSecurityGroup() { - return this.nodeSecurityGroup; + public Output> nodeSecurityGroup() { + return Codegen.optional(this.nodeSecurityGroup); } /** diff --git a/sdk/java/src/main/java/com/pulumi/eks/ClusterArgs.java b/sdk/java/src/main/java/com/pulumi/eks/ClusterArgs.java index 088fa445d..a37583f37 100644 --- a/sdk/java/src/main/java/com/pulumi/eks/ClusterArgs.java +++ b/sdk/java/src/main/java/com/pulumi/eks/ClusterArgs.java @@ -922,6 +922,25 @@ public Optional skipDefaultNodeGroup() { return Optional.ofNullable(this.skipDefaultNodeGroup); } + /** + * If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + * + * See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + * + */ + @Import(name="skipDefaultSecurityGroups") + private @Nullable Boolean skipDefaultSecurityGroups; + + /** + * @return If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + * + * See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + * + */ + public Optional skipDefaultSecurityGroups() { + return Optional.ofNullable(this.skipDefaultSecurityGroups); + } + /** * An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. * @@ -1109,6 +1128,7 @@ private ClusterArgs(ClusterArgs $) { this.roleMappings = $.roleMappings; this.serviceRole = $.serviceRole; this.skipDefaultNodeGroup = $.skipDefaultNodeGroup; + this.skipDefaultSecurityGroups = $.skipDefaultSecurityGroups; this.storageClasses = $.storageClasses; this.subnetIds = $.subnetIds; this.tags = $.tags; @@ -2305,6 +2325,19 @@ public Builder skipDefaultNodeGroup(@Nullable Boolean skipDefaultNodeGroup) { return this; } + /** + * @param skipDefaultSecurityGroups If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + * + * See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + * + * @return builder + * + */ + public Builder skipDefaultSecurityGroups(@Nullable Boolean skipDefaultSecurityGroups) { + $.skipDefaultSecurityGroups = skipDefaultSecurityGroups; + return this; + } + /** * @param storageClasses An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. * diff --git a/sdk/java/src/main/java/com/pulumi/eks/inputs/CoreDataArgs.java b/sdk/java/src/main/java/com/pulumi/eks/inputs/CoreDataArgs.java index 0f2c41e27..0d7a490b3 100644 --- a/sdk/java/src/main/java/com/pulumi/eks/inputs/CoreDataArgs.java +++ b/sdk/java/src/main/java/com/pulumi/eks/inputs/CoreDataArgs.java @@ -79,11 +79,11 @@ public Output clusterIamRole() { return this.clusterIamRole; } - @Import(name="clusterSecurityGroup", required=true) - private Output clusterSecurityGroup; + @Import(name="clusterSecurityGroup") + private @Nullable Output clusterSecurityGroup; - public Output clusterSecurityGroup() { - return this.clusterSecurityGroup; + public Optional> clusterSecurityGroup() { + return Optional.ofNullable(this.clusterSecurityGroup); } @Import(name="eksNodeAccess") @@ -424,7 +424,7 @@ public Builder clusterIamRole(Role clusterIamRole) { return clusterIamRole(Output.of(clusterIamRole)); } - public Builder clusterSecurityGroup(Output clusterSecurityGroup) { + public Builder clusterSecurityGroup(@Nullable Output clusterSecurityGroup) { $.clusterSecurityGroup = clusterSecurityGroup; return this; } @@ -789,9 +789,6 @@ public CoreDataArgs build() { if ($.clusterIamRole == null) { throw new MissingRequiredPropertyException("CoreDataArgs", "clusterIamRole"); } - if ($.clusterSecurityGroup == null) { - throw new MissingRequiredPropertyException("CoreDataArgs", "clusterSecurityGroup"); - } if ($.endpoint == null) { throw new MissingRequiredPropertyException("CoreDataArgs", "endpoint"); } diff --git a/sdk/java/src/main/java/com/pulumi/eks/outputs/CoreData.java b/sdk/java/src/main/java/com/pulumi/eks/outputs/CoreData.java index 3867cdb50..fb1617ef5 100644 --- a/sdk/java/src/main/java/com/pulumi/eks/outputs/CoreData.java +++ b/sdk/java/src/main/java/com/pulumi/eks/outputs/CoreData.java @@ -39,7 +39,7 @@ public final class CoreData { * */ private Role clusterIamRole; - private SecurityGroup clusterSecurityGroup; + private @Nullable SecurityGroup clusterSecurityGroup; private @Nullable ConfigMap eksNodeAccess; private @Nullable ClusterEncryptionConfig encryptionConfig; /** @@ -131,8 +131,8 @@ public Cluster cluster() { public Role clusterIamRole() { return this.clusterIamRole; } - public SecurityGroup clusterSecurityGroup() { - return this.clusterSecurityGroup; + public Optional clusterSecurityGroup() { + return Optional.ofNullable(this.clusterSecurityGroup); } public Optional eksNodeAccess() { return Optional.ofNullable(this.eksNodeAccess); @@ -251,7 +251,7 @@ public static final class Builder { private @Nullable Provider awsProvider; private Cluster cluster; private Role clusterIamRole; - private SecurityGroup clusterSecurityGroup; + private @Nullable SecurityGroup clusterSecurityGroup; private @Nullable ConfigMap eksNodeAccess; private @Nullable ClusterEncryptionConfig encryptionConfig; private String endpoint; @@ -328,10 +328,8 @@ public Builder clusterIamRole(Role clusterIamRole) { return this; } @CustomType.Setter - public Builder clusterSecurityGroup(SecurityGroup clusterSecurityGroup) { - if (clusterSecurityGroup == null) { - throw new MissingRequiredPropertyException("CoreData", "clusterSecurityGroup"); - } + public Builder clusterSecurityGroup(@Nullable SecurityGroup clusterSecurityGroup) { + this.clusterSecurityGroup = clusterSecurityGroup; return this; } diff --git a/sdk/nodejs/cluster.ts b/sdk/nodejs/cluster.ts index 29cdcf740..e0a8991fb 100644 --- a/sdk/nodejs/cluster.ts +++ b/sdk/nodejs/cluster.ts @@ -54,7 +54,7 @@ export class Cluster extends pulumi.ComponentResource { /** * The security group for the EKS cluster. */ - public readonly clusterSecurityGroup!: pulumi.Output; + public readonly clusterSecurityGroup!: pulumi.Output; /** * The EKS cluster and its dependencies. */ @@ -70,7 +70,7 @@ export class Cluster extends pulumi.ComponentResource { /** * The ingress rule that gives node group access to cluster API server. */ - public /*out*/ readonly eksClusterIngressRule!: pulumi.Output; + public /*out*/ readonly eksClusterIngressRule!: pulumi.Output; /** * The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. */ @@ -86,7 +86,7 @@ export class Cluster extends pulumi.ComponentResource { /** * The security group for the cluster's nodes. */ - public /*out*/ readonly nodeSecurityGroup!: pulumi.Output; + public /*out*/ readonly nodeSecurityGroup!: pulumi.Output; /** * Create a Cluster resource with the given unique name, arguments, and options. @@ -143,6 +143,7 @@ export class Cluster extends pulumi.ComponentResource { resourceInputs["roleMappings"] = args ? args.roleMappings : undefined; resourceInputs["serviceRole"] = args ? args.serviceRole : undefined; resourceInputs["skipDefaultNodeGroup"] = args ? args.skipDefaultNodeGroup : undefined; + resourceInputs["skipDefaultSecurityGroups"] = args ? args.skipDefaultSecurityGroups : undefined; resourceInputs["storageClasses"] = args ? args.storageClasses : undefined; resourceInputs["subnetIds"] = args ? args.subnetIds : undefined; resourceInputs["tags"] = args ? args.tags : undefined; @@ -489,6 +490,12 @@ export interface ClusterArgs { * If this toggle is set to true, the EKS cluster will be created without node group attached. Defaults to false, unless `fargate` input is provided. */ skipDefaultNodeGroup?: boolean; + /** + * If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + * + * See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + */ + skipDefaultSecurityGroups?: boolean; /** * An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. * diff --git a/sdk/nodejs/clusterMixins.ts b/sdk/nodejs/clusterMixins.ts index b0907295d..bee5243d7 100644 --- a/sdk/nodejs/clusterMixins.ts +++ b/sdk/nodejs/clusterMixins.ts @@ -74,14 +74,25 @@ Object.defineProperty(Cluster.prototype, 'provider', { }) Cluster.prototype.createNodeGroup = function(name: string, args: ClusterNodeGroupOptionsArgs, awsProvider?: pulumi.ProviderResource): NodeGroup { + const { nodeSecurityGroup, clusterIngressRule } = pulumi.all([this.nodeSecurityGroup, this.eksClusterIngressRule]) + .apply(([nodeSecurityGroup, clusterIngressRule]) => { + if (!nodeSecurityGroup || !clusterIngressRule) { + throw new pulumi.ResourceError( + "The nodeSecurityGroup and eksClusterIngressRule are required when using `createNodeGroup`. Please create the cluster without specifying `skipDefaultNodeGroups`.", + this, + ); + } + + return { nodeSecurityGroup, clusterIngressRule }; + }); return new NodeGroup( name, { ...args, cluster: this.core, - nodeSecurityGroup: this.nodeSecurityGroup, - clusterIngressRule: this.eksClusterIngressRule, + nodeSecurityGroup, + clusterIngressRule, }, { // parent: this, diff --git a/sdk/nodejs/types/input.ts b/sdk/nodejs/types/input.ts index d2697d305..cbe186387 100644 --- a/sdk/nodejs/types/input.ts +++ b/sdk/nodejs/types/input.ts @@ -309,7 +309,7 @@ export interface CoreDataArgs { * The IAM Role attached to the EKS Cluster */ clusterIamRole: pulumi.Input; - clusterSecurityGroup: pulumi.Input; + clusterSecurityGroup?: pulumi.Input; eksNodeAccess?: pulumi.Input; encryptionConfig?: pulumi.Input; /** diff --git a/sdk/nodejs/types/output.ts b/sdk/nodejs/types/output.ts index d110a0089..9b5aab9e2 100644 --- a/sdk/nodejs/types/output.ts +++ b/sdk/nodejs/types/output.ts @@ -309,7 +309,7 @@ export interface CoreData { * The IAM Role attached to the EKS Cluster */ clusterIamRole: pulumiAws.iam.Role; - clusterSecurityGroup: pulumiAws.ec2.SecurityGroup; + clusterSecurityGroup?: pulumiAws.ec2.SecurityGroup; eksNodeAccess?: pulumiKubernetes.core.v1.ConfigMap; encryptionConfig?: pulumiAws.types.output.eks.ClusterEncryptionConfig; /** diff --git a/sdk/python/pulumi_eks/_inputs.py b/sdk/python/pulumi_eks/_inputs.py index 9bfb3ae6b..8dd0d69ce 100644 --- a/sdk/python/pulumi_eks/_inputs.py +++ b/sdk/python/pulumi_eks/_inputs.py @@ -289,7 +289,7 @@ class ClusterNodeGroupOptionsArgsDict(TypedDict): Note: Given the inheritance of auto-generated CF tags and `cloudFormationTags`, you should either supply the tag in `autoScalingGroupTags` or `cloudFormationTags`, but not both. """ - bootstrap_extra_args: NotRequired[str] + bootstrap_extra_args: NotRequired[pulumi.Input[str]] """ Additional args to pass directly to `/etc/eks/bootstrap.sh`. For details on available options, see: https://github.com/awslabs/amazon-eks-ami/blob/master/files/bootstrap.sh. Note that the `--apiserver-endpoint`, `--b64-cluster-ca` and `--kubelet-extra-args` flags are included automatically based on other configuration parameters. """ @@ -370,11 +370,11 @@ class ClusterNodeGroupOptionsArgsDict(TypedDict): """ Name of the key pair to use for SSH access to worker nodes. """ - kubelet_extra_args: NotRequired[str] + kubelet_extra_args: NotRequired[pulumi.Input[str]] """ Extra args to pass to the Kubelet. Corresponds to the options passed in the `--kubeletExtraArgs` flag to `/etc/eks/bootstrap.sh`. For example, '--port=10251 --address=0.0.0.0'. Note that the `labels` and `taints` properties will be applied to this list (using `--node-labels` and `--register-with-taints` respectively) after to the explicit `kubeletExtraArgs`. """ - labels: NotRequired[Mapping[str, str]] + labels: NotRequired[pulumi.Input[Mapping[str, pulumi.Input[str]]]] """ Custom k8s node labels to be attached to each worker node. Adds the given key/value pairs to the `--node-labels` kubelet argument. """ @@ -394,7 +394,7 @@ class ClusterNodeGroupOptionsArgsDict(TypedDict): """ The minimum number of worker nodes running in the cluster. Defaults to 1. """ - node_associate_public_ip_address: NotRequired[bool] + node_associate_public_ip_address: NotRequired[pulumi.Input[bool]] """ Whether or not to auto-assign public IP addresses on the EKS worker nodes. If this toggle is set to true, the EKS workers will be auto-assigned public IPs. If false, they will not be auto-assigned public IPs. """ @@ -480,7 +480,7 @@ class ClusterNodeGroupOptionsArgsDict(TypedDict): """ Bidding price for spot instance. If set, only spot instances will be added as worker node. """ - taints: NotRequired[Mapping[str, 'TaintArgsDict']] + taints: NotRequired[pulumi.Input[Mapping[str, pulumi.Input['TaintArgsDict']]]] """ Custom k8s node taints to be attached to each worker node. Adds the given taints to the `--register-with-taints` kubelet argument """ @@ -1273,7 +1273,6 @@ class CoreDataArgsDict(TypedDict): """ The IAM Role attached to the EKS Cluster """ - cluster_security_group: pulumi.Input['pulumi_aws.ec2.SecurityGroup'] endpoint: pulumi.Input[str] """ The EKS cluster's Kubernetes API server endpoint. @@ -1300,6 +1299,7 @@ class CoreDataArgsDict(TypedDict): The access entries added to the cluster. """ aws_provider: NotRequired[pulumi.Input['pulumi_aws.Provider']] + cluster_security_group: NotRequired[pulumi.Input['pulumi_aws.ec2.SecurityGroup']] eks_node_access: NotRequired[pulumi.Input['pulumi_kubernetes.core.v1.ConfigMap']] encryption_config: NotRequired[pulumi.Input['pulumi_aws.eks.ClusterEncryptionConfigArgs']] fargate_profile: NotRequired[pulumi.Input['pulumi_aws.eks.FargateProfile']] @@ -1343,7 +1343,6 @@ class CoreDataArgs: def __init__(__self__, *, cluster: pulumi.Input['pulumi_aws.eks.Cluster'], cluster_iam_role: pulumi.Input['pulumi_aws.iam.Role'], - cluster_security_group: pulumi.Input['pulumi_aws.ec2.SecurityGroup'], endpoint: pulumi.Input[str], instance_roles: pulumi.Input[Sequence[pulumi.Input['pulumi_aws.iam.Role']]], node_group_options: pulumi.Input['ClusterNodeGroupOptionsArgs'], @@ -1352,6 +1351,7 @@ def __init__(__self__, *, vpc_id: pulumi.Input[str], access_entries: Optional[pulumi.Input[Sequence[pulumi.Input['AccessEntryArgs']]]] = None, aws_provider: Optional[pulumi.Input['pulumi_aws.Provider']] = None, + cluster_security_group: Optional[pulumi.Input['pulumi_aws.ec2.SecurityGroup']] = None, eks_node_access: Optional[pulumi.Input['pulumi_kubernetes.core.v1.ConfigMap']] = None, encryption_config: Optional[pulumi.Input['pulumi_aws.eks.ClusterEncryptionConfigArgs']] = None, fargate_profile: Optional[pulumi.Input['pulumi_aws.eks.FargateProfile']] = None, @@ -1383,7 +1383,6 @@ def __init__(__self__, *, """ pulumi.set(__self__, "cluster", cluster) pulumi.set(__self__, "cluster_iam_role", cluster_iam_role) - pulumi.set(__self__, "cluster_security_group", cluster_security_group) pulumi.set(__self__, "endpoint", endpoint) pulumi.set(__self__, "instance_roles", instance_roles) pulumi.set(__self__, "node_group_options", node_group_options) @@ -1394,6 +1393,8 @@ def __init__(__self__, *, pulumi.set(__self__, "access_entries", access_entries) if aws_provider is not None: pulumi.set(__self__, "aws_provider", aws_provider) + if cluster_security_group is not None: + pulumi.set(__self__, "cluster_security_group", cluster_security_group) if eks_node_access is not None: pulumi.set(__self__, "eks_node_access", eks_node_access) if encryption_config is not None: @@ -1438,15 +1439,6 @@ def cluster_iam_role(self) -> pulumi.Input['pulumi_aws.iam.Role']: def cluster_iam_role(self, value: pulumi.Input['pulumi_aws.iam.Role']): pulumi.set(self, "cluster_iam_role", value) - @property - @pulumi.getter(name="clusterSecurityGroup") - def cluster_security_group(self) -> pulumi.Input['pulumi_aws.ec2.SecurityGroup']: - return pulumi.get(self, "cluster_security_group") - - @cluster_security_group.setter - def cluster_security_group(self, value: pulumi.Input['pulumi_aws.ec2.SecurityGroup']): - pulumi.set(self, "cluster_security_group", value) - @property @pulumi.getter def endpoint(self) -> pulumi.Input[str]: @@ -1537,6 +1529,15 @@ def aws_provider(self) -> Optional[pulumi.Input['pulumi_aws.Provider']]: def aws_provider(self, value: Optional[pulumi.Input['pulumi_aws.Provider']]): pulumi.set(self, "aws_provider", value) + @property + @pulumi.getter(name="clusterSecurityGroup") + def cluster_security_group(self) -> Optional[pulumi.Input['pulumi_aws.ec2.SecurityGroup']]: + return pulumi.get(self, "cluster_security_group") + + @cluster_security_group.setter + def cluster_security_group(self, value: Optional[pulumi.Input['pulumi_aws.ec2.SecurityGroup']]): + pulumi.set(self, "cluster_security_group", value) + @property @pulumi.getter(name="eksNodeAccess") def eks_node_access(self) -> Optional[pulumi.Input['pulumi_kubernetes.core.v1.ConfigMap']]: @@ -2507,11 +2508,11 @@ class TaintArgsDict(TypedDict): """ Represents a Kubernetes `taint` to apply to all Nodes in a NodeGroup. See https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/. """ - effect: str + effect: pulumi.Input[str] """ The effect of the taint. """ - value: str + value: pulumi.Input[str] """ The value of the taint. """ diff --git a/sdk/python/pulumi_eks/cluster.py b/sdk/python/pulumi_eks/cluster.py index c114fc8d3..d71c891c9 100644 --- a/sdk/python/pulumi_eks/cluster.py +++ b/sdk/python/pulumi_eks/cluster.py @@ -69,6 +69,7 @@ def __init__(__self__, *, role_mappings: Optional[pulumi.Input[Sequence[pulumi.Input['RoleMappingArgs']]]] = None, service_role: Optional[pulumi.Input['pulumi_aws.iam.Role']] = None, skip_default_node_group: Optional[bool] = None, + skip_default_security_groups: Optional[bool] = None, storage_classes: Optional[Union[str, Mapping[str, 'StorageClassArgs']]] = None, subnet_ids: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, @@ -237,6 +238,9 @@ def __init__(__self__, *, :param pulumi.Input[Sequence[pulumi.Input['RoleMappingArgs']]] role_mappings: Optional mappings from AWS IAM roles to Kubernetes users and groups. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP` :param pulumi.Input['pulumi_aws.iam.Role'] service_role: IAM Service Role for EKS to use to manage the cluster. :param bool skip_default_node_group: If this toggle is set to true, the EKS cluster will be created without node group attached. Defaults to false, unless `fargate` input is provided. + :param bool skip_default_security_groups: If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + + See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html :param Union[str, Mapping[str, 'StorageClassArgs']] storage_classes: An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. Note: As of Kubernetes v1.11+ on EKS, a default `gp2` storage class will always be created automatically for the cluster by the EKS service. See https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html @@ -344,6 +348,8 @@ def __init__(__self__, *, pulumi.set(__self__, "service_role", service_role) if skip_default_node_group is not None: pulumi.set(__self__, "skip_default_node_group", skip_default_node_group) + if skip_default_security_groups is not None: + pulumi.set(__self__, "skip_default_security_groups", skip_default_security_groups) if storage_classes is not None: pulumi.set(__self__, "storage_classes", storage_classes) if subnet_ids is not None: @@ -1003,6 +1009,20 @@ def skip_default_node_group(self) -> Optional[bool]: def skip_default_node_group(self, value: Optional[bool]): pulumi.set(self, "skip_default_node_group", value) + @property + @pulumi.getter(name="skipDefaultSecurityGroups") + def skip_default_security_groups(self) -> Optional[bool]: + """ + If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + + See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html + """ + return pulumi.get(self, "skip_default_security_groups") + + @skip_default_security_groups.setter + def skip_default_security_groups(self, value: Optional[bool]): + pulumi.set(self, "skip_default_security_groups", value) + @property @pulumi.getter(name="storageClasses") def storage_classes(self) -> Optional[Union[str, Mapping[str, 'StorageClassArgs']]]: @@ -1159,6 +1179,7 @@ def __init__(__self__, role_mappings: Optional[pulumi.Input[Sequence[pulumi.Input[Union['RoleMappingArgs', 'RoleMappingArgsDict']]]]] = None, service_role: Optional[pulumi.Input['pulumi_aws.iam.Role']] = None, skip_default_node_group: Optional[bool] = None, + skip_default_security_groups: Optional[bool] = None, storage_classes: Optional[Union[str, Mapping[str, Union['StorageClassArgs', 'StorageClassArgsDict']]]] = None, subnet_ids: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, @@ -1349,6 +1370,9 @@ def __init__(__self__, :param pulumi.Input[Sequence[pulumi.Input[Union['RoleMappingArgs', 'RoleMappingArgsDict']]]] role_mappings: Optional mappings from AWS IAM roles to Kubernetes users and groups. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP` :param pulumi.Input['pulumi_aws.iam.Role'] service_role: IAM Service Role for EKS to use to manage the cluster. :param bool skip_default_node_group: If this toggle is set to true, the EKS cluster will be created without node group attached. Defaults to false, unless `fargate` input is provided. + :param bool skip_default_security_groups: If this toggle is set to true, the EKS cluster will be created without the default node and cluster security groups. Defaults to false. + + See for more details: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html :param Union[str, Mapping[str, Union['StorageClassArgs', 'StorageClassArgsDict']]] storage_classes: An optional set of StorageClasses to enable for the cluster. If this is a single volume type rather than a map, a single StorageClass will be created for that volume type. Note: As of Kubernetes v1.11+ on EKS, a default `gp2` storage class will always be created automatically for the cluster by the EKS service. See https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html @@ -1454,6 +1478,7 @@ def _internal_init(__self__, role_mappings: Optional[pulumi.Input[Sequence[pulumi.Input[Union['RoleMappingArgs', 'RoleMappingArgsDict']]]]] = None, service_role: Optional[pulumi.Input['pulumi_aws.iam.Role']] = None, skip_default_node_group: Optional[bool] = None, + skip_default_security_groups: Optional[bool] = None, storage_classes: Optional[Union[str, Mapping[str, Union['StorageClassArgs', 'StorageClassArgsDict']]]] = None, subnet_ids: Optional[pulumi.Input[Sequence[pulumi.Input[str]]]] = None, tags: Optional[pulumi.Input[Mapping[str, pulumi.Input[str]]]] = None, @@ -1517,6 +1542,7 @@ def _internal_init(__self__, __props__.__dict__["role_mappings"] = role_mappings __props__.__dict__["service_role"] = service_role __props__.__dict__["skip_default_node_group"] = skip_default_node_group + __props__.__dict__["skip_default_security_groups"] = skip_default_security_groups __props__.__dict__["storage_classes"] = storage_classes __props__.__dict__["subnet_ids"] = subnet_ids __props__.__dict__["tags"] = tags @@ -1550,7 +1576,7 @@ def aws_provider(self) -> pulumi.Output['pulumi_aws.Provider']: @property @pulumi.getter(name="clusterSecurityGroup") - def cluster_security_group(self) -> pulumi.Output['pulumi_aws.ec2.SecurityGroup']: + def cluster_security_group(self) -> pulumi.Output[Optional['pulumi_aws.ec2.SecurityGroup']]: """ The security group for the EKS cluster. """ @@ -1582,7 +1608,7 @@ def eks_cluster(self) -> pulumi.Output['pulumi_aws.eks.Cluster']: @property @pulumi.getter(name="eksClusterIngressRule") - def eks_cluster_ingress_rule(self) -> pulumi.Output['pulumi_aws.ec2.SecurityGroupRule']: + def eks_cluster_ingress_rule(self) -> pulumi.Output[Optional['pulumi_aws.ec2.SecurityGroupRule']]: """ The ingress rule that gives node group access to cluster API server. """ @@ -1614,7 +1640,7 @@ def kubeconfig_json(self) -> pulumi.Output[str]: @property @pulumi.getter(name="nodeSecurityGroup") - def node_security_group(self) -> pulumi.Output['pulumi_aws.ec2.SecurityGroup']: + def node_security_group(self) -> pulumi.Output[Optional['pulumi_aws.ec2.SecurityGroup']]: """ The security group for the cluster's nodes. """ diff --git a/sdk/python/pulumi_eks/outputs.py b/sdk/python/pulumi_eks/outputs.py index ca671c72e..6e8f77b54 100644 --- a/sdk/python/pulumi_eks/outputs.py +++ b/sdk/python/pulumi_eks/outputs.py @@ -912,8 +912,6 @@ def __key_warning(key: str): suggest = None if key == "clusterIamRole": suggest = "cluster_iam_role" - elif key == "clusterSecurityGroup": - suggest = "cluster_security_group" elif key == "instanceRoles": suggest = "instance_roles" elif key == "nodeGroupOptions": @@ -926,6 +924,8 @@ def __key_warning(key: str): suggest = "access_entries" elif key == "awsProvider": suggest = "aws_provider" + elif key == "clusterSecurityGroup": + suggest = "cluster_security_group" elif key == "eksNodeAccess": suggest = "eks_node_access" elif key == "encryptionConfig": @@ -959,7 +959,6 @@ def get(self, key: str, default = None) -> Any: def __init__(__self__, *, cluster: 'pulumi_aws.eks.Cluster', cluster_iam_role: 'pulumi_aws.iam.Role', - cluster_security_group: 'pulumi_aws.ec2.SecurityGroup', endpoint: str, instance_roles: Sequence['pulumi_aws.iam.Role'], node_group_options: 'outputs.ClusterNodeGroupOptions', @@ -968,6 +967,7 @@ def __init__(__self__, *, vpc_id: str, access_entries: Optional[Sequence['outputs.AccessEntry']] = None, aws_provider: Optional['pulumi_aws.Provider'] = None, + cluster_security_group: Optional['pulumi_aws.ec2.SecurityGroup'] = None, eks_node_access: Optional['pulumi_kubernetes.core.v1.ConfigMap'] = None, encryption_config: Optional['pulumi_aws.eks.outputs.ClusterEncryptionConfig'] = None, fargate_profile: Optional['pulumi_aws.eks.FargateProfile'] = None, @@ -999,7 +999,6 @@ def __init__(__self__, *, """ pulumi.set(__self__, "cluster", cluster) pulumi.set(__self__, "cluster_iam_role", cluster_iam_role) - pulumi.set(__self__, "cluster_security_group", cluster_security_group) pulumi.set(__self__, "endpoint", endpoint) pulumi.set(__self__, "instance_roles", instance_roles) pulumi.set(__self__, "node_group_options", node_group_options) @@ -1010,6 +1009,8 @@ def __init__(__self__, *, pulumi.set(__self__, "access_entries", access_entries) if aws_provider is not None: pulumi.set(__self__, "aws_provider", aws_provider) + if cluster_security_group is not None: + pulumi.set(__self__, "cluster_security_group", cluster_security_group) if eks_node_access is not None: pulumi.set(__self__, "eks_node_access", eks_node_access) if encryption_config is not None: @@ -1046,11 +1047,6 @@ def cluster_iam_role(self) -> 'pulumi_aws.iam.Role': """ return pulumi.get(self, "cluster_iam_role") - @property - @pulumi.getter(name="clusterSecurityGroup") - def cluster_security_group(self) -> 'pulumi_aws.ec2.SecurityGroup': - return pulumi.get(self, "cluster_security_group") - @property @pulumi.getter def endpoint(self) -> str: @@ -1109,6 +1105,11 @@ def access_entries(self) -> Optional[Sequence['outputs.AccessEntry']]: def aws_provider(self) -> Optional['pulumi_aws.Provider']: return pulumi.get(self, "aws_provider") + @property + @pulumi.getter(name="clusterSecurityGroup") + def cluster_security_group(self) -> Optional['pulumi_aws.ec2.SecurityGroup']: + return pulumi.get(self, "cluster_security_group") + @property @pulumi.getter(name="eksNodeAccess") def eks_node_access(self) -> Optional['pulumi_kubernetes.core.v1.ConfigMap']: