From 50c6dcf4e8fe0c5d79e9d1afd3ba4bacc25a47cb Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 10:53:25 +0200 Subject: [PATCH 01/10] Mark VpcCniAddon as component --- provider/cmd/pulumi-gen-eks/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/provider/cmd/pulumi-gen-eks/main.go b/provider/cmd/pulumi-gen-eks/main.go index 7dc7e4421..85dfc7929 100644 --- a/provider/cmd/pulumi-gen-eks/main.go +++ b/provider/cmd/pulumi-gen-eks/main.go @@ -1103,6 +1103,7 @@ func generateSchema(version semver.Version) schema.PackageSpec { }, }, "eks:index:VpcCniAddon": { + IsComponent: true, ObjectTypeSpec: schema.ObjectTypeSpec{ Description: "VpcCniAddon manages the configuration of the Amazon VPC CNI plugin for Kubernetes by leveraging the EKS managed add-on.\n" + "For more information see: https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html", From c8e881b771858e0e6f0ce2d93f0dcbc73817f474 Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 11:46:31 +0200 Subject: [PATCH 02/10] Add scalar properties for nested optional resources --- provider/cmd/pulumi-gen-eks/main.go | 52 ++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/provider/cmd/pulumi-gen-eks/main.go b/provider/cmd/pulumi-gen-eks/main.go index 85dfc7929..9e68c9771 100644 --- a/provider/cmd/pulumi-gen-eks/main.go +++ b/provider/cmd/pulumi-gen-eks/main.go @@ -199,10 +199,6 @@ func generateSchema(version semver.Version) schema.PackageSpec { TypeSpec: schema.TypeSpec{Ref: awsRef("#/provider")}, Description: "The AWS resource provider.", }, - // "provider": { - // TypeSpec: schema.TypeSpec{Ref: k8sRef("#/provider")}, - // Description: "A Kubernetes resource provider that can be used to deploy into this cluster.", - // }, "clusterSecurityGroup": { TypeSpec: schema.TypeSpec{Ref: awsRef("#/resources/aws:ec2%2FsecurityGroup:SecurityGroup")}, Description: "The security group for the EKS cluster.", @@ -235,15 +231,61 @@ func generateSchema(version semver.Version) schema.PackageSpec { TypeSpec: schema.TypeSpec{Ref: "#/types/eks:index:CoreData"}, Description: "The EKS cluster and its dependencies.", }, + "clusterSecurityGroupId": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true.", + }, + "nodeSecurityGroupId": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true.", + }, + "clusterIngressRuleId": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true.", + }, + "defaultNodeGroupAsgName": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true.", + }, + "fargateProfileId": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured.", + }, + "fargateProfileStatus": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured.", + }, + "oidcProviderArn": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured.", + }, + "oidcProviderUrl": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "Issuer URL for the OpenID Connect identity provider of the EKS cluster.", + }, + "oidcIssuer": { + TypeSpec: schema.TypeSpec{Type: "string"}, + Description: "The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`).\n\n" + + "This value can be used to associate kubernetes service accounts with IAM roles. For more information, see " + + "https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html.", + }, }, Required: []string{ "kubeconfig", "kubeconfigJson", "awsProvider", - // "provider", "instanceRoles", "eksCluster", "core", + "clusterSecurityGroupId", + "nodeSecurityGroupId", + "clusterIngressRuleId", + "defaultNodeGroupAsgName", + "fargateProfileId", + "fargateProfileStatus", + "oidcProviderArn", + "oidcProviderUrl", + "oidcIssuer", }, }, InputProperties: map[string]schema.PropertySpec{ From b4a62b57c7b980e87f464d4fac12c24d9d3c753b Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 11:55:04 +0200 Subject: [PATCH 03/10] Wire up new scalar properties --- nodejs/eks/cluster.ts | 69 ++++++++++++++++++++++++++++++ nodejs/eks/cmd/provider/cluster.ts | 9 ++++ 2 files changed, 78 insertions(+) diff --git a/nodejs/eks/cluster.ts b/nodejs/eks/cluster.ts index f13f60d39..577a65e63 100644 --- a/nodejs/eks/cluster.ts +++ b/nodejs/eks/cluster.ts @@ -1992,6 +1992,15 @@ export interface ClusterResult { defaultNodeGroup: NodeGroupV2Data | undefined; eksCluster: aws.eks.Cluster; core: CoreData; + clusterSecurityGroupId: pulumi.Output; + nodeSecurityGroupId: pulumi.Output; + clusterIngressRuleId: pulumi.Output; + defaultNodeGroupAsgName: pulumi.Output; + fargateProfileId: pulumi.Output; + fargateProfileStatus: pulumi.Output; + oidcProviderArn: pulumi.Output; + oidcProviderUrl: pulumi.Output; + oidcIssuer: pulumi.Output; } /** @internal */ @@ -2074,6 +2083,16 @@ export function createCluster( const kubeconfigJson = pulumi.jsonStringify(core.kubeconfig); + const oidcIssuerUrl = core.cluster.identities.apply(identities => { + // this is nowadays guaranteed to be present, but we still check for it to be safe + // this was not set for cluster version 1.14 and below. Those versions are not available anymore + // since 2020-12-08 and clusters were force upgraded + if (identities && identities.length > 0 && identities[0].oidcs && identities[0].oidcs.length > 0) { + return identities[0].oidcs[0].issuer; + } + return ""; + }); + return { core, clusterSecurityGroup: core.clusterSecurityGroup, @@ -2085,6 +2104,19 @@ export function createCluster( defaultNodeGroup, kubeconfig: pulumi.output(core.kubeconfig), kubeconfigJson, + // If the cluster is created without default security groups, we're returning the EKS created security group + // see: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html#security-group-default-rules + clusterSecurityGroupId: core.clusterSecurityGroup?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId, + nodeSecurityGroupId: nodeSecurityGroup?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId, + + clusterIngressRuleId: eksClusterIngressRule?.securityGroupRuleId ?? pulumi.output(""), + defaultNodeGroupAsgName: defaultNodeGroup?.autoScalingGroup.name ?? pulumi.output(""), + fargateProfileId: core.fargateProfile.apply(fargateProfile => fargateProfile?.id ?? pulumi.output("")), + fargateProfileStatus: core.fargateProfile.apply(fargateProfile => fargateProfile?.status ?? pulumi.output("")), + oidcProviderArn: core.oidcProvider?.arn ?? pulumi.output(""), + oidcProviderUrl: oidcIssuerUrl, + // The issuer is the issuer URL without the protocol part + oidcIssuer: oidcIssuerUrl.apply(url => url.replace("https://", "")), }; } @@ -2110,6 +2142,16 @@ export class ClusterInternal extends pulumi.ComponentResource { public readonly kubeconfigJson!: pulumi.Output; public readonly nodeSecurityGroup!: pulumi.Output; + public readonly clusterSecurityGroupId: pulumi.Output; + public readonly nodeSecurityGroupId: pulumi.Output; + public readonly clusterIngressRuleId: pulumi.Output; + public readonly defaultNodeGroupAsgName: pulumi.Output; + public readonly fargateProfileId: pulumi.Output; + public readonly fargateProfileStatus: pulumi.Output; + public readonly oidcProviderArn: pulumi.Output; + public readonly oidcProviderUrl: pulumi.Output; + public readonly oidcIssuer: pulumi.Output; + constructor(name: string, args?: ClusterOptions, opts?: pulumi.ComponentResourceOptions) { const type = "eks:index:Cluster"; @@ -2124,6 +2166,15 @@ export class ClusterInternal extends pulumi.ComponentResource { kubeconfig: undefined, kubeconfigJson: undefined, nodeSecurityGroup: undefined, + clusterSecurityGroupId: undefined, + nodeSecurityGroupId: undefined, + clusterIngressRuleId: undefined, + defaultNodeGroupAsgName: undefined, + fargateProfileId: undefined, + fargateProfileStatus: undefined, + oidcProviderArn: undefined, + oidcProviderUrl: undefined, + oidcIssuer: undefined, }; super(type, name, props, opts); return; @@ -2147,6 +2198,15 @@ export class ClusterInternal extends pulumi.ComponentResource { this.defaultNodeGroup = pulumi.output(cluster.defaultNodeGroup); this.eksCluster = pulumi.output(cluster.eksCluster); this.core = pulumi.output(cluster.core); + this.clusterSecurityGroupId = pulumi.output(cluster.clusterSecurityGroupId); + this.nodeSecurityGroupId = pulumi.output(cluster.nodeSecurityGroupId); + this.clusterIngressRuleId = pulumi.output(cluster.clusterIngressRuleId); + this.defaultNodeGroupAsgName = pulumi.output(cluster.defaultNodeGroupAsgName); + this.fargateProfileId = pulumi.output(cluster.fargateProfileId); + this.fargateProfileStatus = pulumi.output(cluster.fargateProfileStatus); + this.oidcProviderArn = pulumi.output(cluster.oidcProviderArn); + this.oidcProviderUrl = pulumi.output(cluster.oidcProviderUrl); + this.oidcIssuer = pulumi.output(cluster.oidcIssuer); this.registerOutputs({ clusterSecurityGroup: this.clusterSecurityGroup, @@ -2158,6 +2218,15 @@ export class ClusterInternal extends pulumi.ComponentResource { kubeconfig: this.kubeconfig, kubeconfigJson: this.kubeconfigJson, nodeSecurityGroup: this.nodeSecurityGroup, + clusterSecurityGroupId: this.clusterSecurityGroupId, + nodeSecurityGroupId: this.nodeSecurityGroupId, + clusterIngressRuleId: this.clusterIngressRuleId, + defaultNodeGroupAsgName: this.defaultNodeGroupAsgName, + fargateProfileId: this.fargateProfileId, + fargateProfileStatus: this.fargateProfileStatus, + oidcProviderArn: this.oidcProviderArn, + oidcProviderUrl: this.oidcProviderUrl, + oidcIssuer: this.oidcIssuer, }); } diff --git a/nodejs/eks/cmd/provider/cluster.ts b/nodejs/eks/cmd/provider/cluster.ts index 2d8cf3a69..5f76abff6 100644 --- a/nodejs/eks/cmd/provider/cluster.ts +++ b/nodejs/eks/cmd/provider/cluster.ts @@ -36,6 +36,15 @@ const clusterProvider: pulumi.provider.Provider = { defaultNodeGroup: cluster.defaultNodeGroup, eksCluster: cluster.eksCluster, core: cluster.core, + clusterSecurityGroupId: cluster.clusterSecurityGroupId, + nodeSecurityGroupId: cluster.nodeSecurityGroupId, + clusterIngressRuleId: cluster.clusterIngressRuleId, + defaultNodeGroupAsgName: cluster.defaultNodeGroupAsgName, + fargateProfileId: cluster.fargateProfileId, + fargateProfileStatus: cluster.fargateProfileStatus, + oidcProviderArn: cluster.oidcProviderArn, + oidcProviderUrl: cluster.oidcProviderUrl, + oidcIssuer: cluster.oidcIssuer, }, }); } catch (e) { From 61c2c0d57a05dd3ee16089e98cfaed818e8655c7 Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 11:55:21 +0200 Subject: [PATCH 04/10] Regenerate schema --- provider/cmd/pulumi-resource-eks/schema.json | 50 +++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/provider/cmd/pulumi-resource-eks/schema.json b/provider/cmd/pulumi-resource-eks/schema.json index 3d3abc314..8ffc7bfce 100644 --- a/provider/cmd/pulumi-resource-eks/schema.json +++ b/provider/cmd/pulumi-resource-eks/schema.json @@ -1077,10 +1077,18 @@ "$ref": "/aws/v6.18.2/schema.json#/provider", "description": "The AWS resource provider." }, + "clusterIngressRuleId": { + "type": "string", + "description": "The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true." + }, "clusterSecurityGroup": { "$ref": "/aws/v6.18.2/schema.json#/resources/aws:ec2%2FsecurityGroup:SecurityGroup", "description": "The security group for the EKS cluster." }, + "clusterSecurityGroupId": { + "type": "string", + "description": "The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true." + }, "core": { "$ref": "#/types/eks:index:CoreData", "description": "The EKS cluster and its dependencies." @@ -1089,6 +1097,10 @@ "$ref": "#/types/eks:index:NodeGroupData", "description": "The default Node Group configuration, or undefined if `skipDefaultNodeGroup` was specified." }, + "defaultNodeGroupAsgName": { + "type": "string", + "description": "The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true." + }, "eksCluster": { "$ref": "/aws/v6.18.2/schema.json#/resources/aws:eks%2Fcluster:Cluster", "description": "The EKS cluster." @@ -1097,6 +1109,14 @@ "$ref": "/aws/v6.18.2/schema.json#/resources/aws:ec2%2FsecurityGroupRule:SecurityGroupRule", "description": "The ingress rule that gives node group access to cluster API server." }, + "fargateProfileId": { + "type": "string", + "description": "The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured." + }, + "fargateProfileStatus": { + "type": "string", + "description": "The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured." + }, "instanceRoles": { "type": "array", "items": { @@ -1115,6 +1135,22 @@ "nodeSecurityGroup": { "$ref": "/aws/v6.18.2/schema.json#/resources/aws:ec2%2FsecurityGroup:SecurityGroup", "description": "The security group for the cluster's nodes." + }, + "nodeSecurityGroupId": { + "type": "string", + "description": "The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true." + }, + "oidcIssuer": { + "type": "string", + "description": "The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`).\n\nThis value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html." + }, + "oidcProviderArn": { + "type": "string", + "description": "The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured." + }, + "oidcProviderUrl": { + "type": "string", + "description": "Issuer URL for the OpenID Connect identity provider of the EKS cluster." } }, "required": [ @@ -1123,7 +1159,16 @@ "awsProvider", "instanceRoles", "eksCluster", - "core" + "core", + "clusterSecurityGroupId", + "nodeSecurityGroupId", + "clusterIngressRuleId", + "defaultNodeGroupAsgName", + "fargateProfileId", + "fargateProfileStatus", + "oidcProviderArn", + "oidcProviderUrl", + "oidcIssuer" ], "inputProperties": { "accessEntries": { @@ -2235,7 +2280,8 @@ { "type": "eks:index:VpcCni" } - ] + ], + "isComponent": true } }, "functions": { From 7011c5c803bf000c545aa22cca7a750bc053f18c Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 11:55:35 +0200 Subject: [PATCH 05/10] Regenerate SDK --- sdk/dotnet/Cluster.cs | 56 ++++++++ sdk/dotnet/VpcCniAddon.cs | 29 +--- sdk/go/eks/cluster.go | 67 +++++++++ sdk/go/eks/vpcCniAddon.go | 27 +--- .../src/main/java/com/pulumi/eks/Cluster.java | 130 ++++++++++++++++++ .../main/java/com/pulumi/eks/VpcCniAddon.java | 29 +--- sdk/nodejs/cluster.ts | 56 ++++++++ sdk/nodejs/vpcCniAddon.ts | 18 +-- sdk/python/pulumi_eks/cluster.py | 83 +++++++++++ sdk/python/pulumi_eks/vpc_cni_addon.py | 27 +--- 10 files changed, 416 insertions(+), 106 deletions(-) diff --git a/sdk/dotnet/Cluster.cs b/sdk/dotnet/Cluster.cs index f6cacb486..40794d484 100644 --- a/sdk/dotnet/Cluster.cs +++ b/sdk/dotnet/Cluster.cs @@ -47,12 +47,24 @@ public partial class Cluster : global::Pulumi.ComponentResource [Output("awsProvider")] public Output AwsProvider { get; private set; } = null!; + /// + /// The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. + /// + [Output("clusterIngressRuleId")] + public Output ClusterIngressRuleId { get; private set; } = null!; + /// /// The security group for the EKS cluster. /// [Output("clusterSecurityGroup")] public Output ClusterSecurityGroup { get; private set; } = null!; + /// + /// The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + /// + [Output("clusterSecurityGroupId")] + public Output ClusterSecurityGroupId { get; private set; } = null!; + /// /// The EKS cluster and its dependencies. /// @@ -65,6 +77,12 @@ public partial class Cluster : global::Pulumi.ComponentResource [Output("defaultNodeGroup")] public Output DefaultNodeGroup { get; private set; } = null!; + /// + /// The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. + /// + [Output("defaultNodeGroupAsgName")] + public Output DefaultNodeGroupAsgName { get; private set; } = null!; + /// /// The EKS cluster. /// @@ -77,6 +95,18 @@ public partial class Cluster : global::Pulumi.ComponentResource [Output("eksClusterIngressRule")] public Output EksClusterIngressRule { get; private set; } = null!; + /// + /// The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + /// + [Output("fargateProfileId")] + public Output FargateProfileId { get; private set; } = null!; + + /// + /// The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + /// + [Output("fargateProfileStatus")] + public Output FargateProfileStatus { get; private set; } = null!; + /// /// The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. /// @@ -101,6 +131,32 @@ public partial class Cluster : global::Pulumi.ComponentResource [Output("nodeSecurityGroup")] public Output NodeSecurityGroup { get; private set; } = null!; + /// + /// The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + /// + [Output("nodeSecurityGroupId")] + public Output NodeSecurityGroupId { get; private set; } = null!; + + /// + /// The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). + /// + /// This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. + /// + [Output("oidcIssuer")] + public Output OidcIssuer { get; private set; } = null!; + + /// + /// The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. + /// + [Output("oidcProviderArn")] + public Output OidcProviderArn { get; private set; } = null!; + + /// + /// Issuer URL for the OpenID Connect identity provider of the EKS cluster. + /// + [Output("oidcProviderUrl")] + public Output OidcProviderUrl { get; private set; } = null!; + /// /// Create a Cluster resource with the given unique name, arguments, and options. diff --git a/sdk/dotnet/VpcCniAddon.cs b/sdk/dotnet/VpcCniAddon.cs index 66899a242..55d1fdedf 100644 --- a/sdk/dotnet/VpcCniAddon.cs +++ b/sdk/dotnet/VpcCniAddon.cs @@ -14,7 +14,7 @@ namespace Pulumi.Eks /// For more information see: https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html /// [EksResourceType("eks:index:VpcCniAddon")] - public partial class VpcCniAddon : global::Pulumi.CustomResource + public partial class VpcCniAddon : global::Pulumi.ComponentResource { /// /// Create a VpcCniAddon resource with the given unique name, arguments, and options. @@ -23,19 +23,14 @@ public partial class VpcCniAddon : global::Pulumi.CustomResource /// The unique name of the resource /// The arguments used to populate this resource's properties /// A bag of options that control this resource's behavior - public VpcCniAddon(string name, VpcCniAddonArgs args, CustomResourceOptions? options = null) - : base("eks:index:VpcCniAddon", name, args ?? new VpcCniAddonArgs(), MakeResourceOptions(options, "")) + public VpcCniAddon(string name, VpcCniAddonArgs args, ComponentResourceOptions? options = null) + : base("eks:index:VpcCniAddon", name, args ?? new VpcCniAddonArgs(), MakeResourceOptions(options, ""), remote: true) { } - private VpcCniAddon(string name, Input id, CustomResourceOptions? options = null) - : base("eks:index:VpcCniAddon", name, null, MakeResourceOptions(options, id)) + private static ComponentResourceOptions MakeResourceOptions(ComponentResourceOptions? options, Input? id) { - } - - private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? options, Input? id) - { - var defaultOptions = new CustomResourceOptions + var defaultOptions = new ComponentResourceOptions { Version = Utilities.Version, Aliases = @@ -43,23 +38,11 @@ private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? new global::Pulumi.Alias { Type = "eks:index:VpcCni" }, }, }; - var merged = CustomResourceOptions.Merge(defaultOptions, options); + var merged = ComponentResourceOptions.Merge(defaultOptions, options); // Override the ID if one was specified for consistency with other language SDKs. merged.Id = id ?? merged.Id; return merged; } - /// - /// Get an existing VpcCniAddon resource's state with the given name, ID, and optional extra - /// properties used to qualify the lookup. - /// - /// - /// The unique name of the resulting resource. - /// The unique provider ID of the resource to lookup. - /// A bag of options that control this resource's behavior - public static VpcCniAddon Get(string name, Input id, CustomResourceOptions? options = null) - { - return new VpcCniAddon(name, id, options); - } } public sealed class VpcCniAddonArgs : global::Pulumi.ResourceArgs diff --git a/sdk/go/eks/cluster.go b/sdk/go/eks/cluster.go index 559403712..6e60fc65d 100644 --- a/sdk/go/eks/cluster.go +++ b/sdk/go/eks/cluster.go @@ -52,16 +52,26 @@ type Cluster struct { // The AWS resource provider. AwsProvider aws.ProviderOutput `pulumi:"awsProvider"` + // The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. + ClusterIngressRuleId pulumi.StringOutput `pulumi:"clusterIngressRuleId"` // The security group for the EKS cluster. ClusterSecurityGroup ec2.SecurityGroupOutput `pulumi:"clusterSecurityGroup"` + // The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + ClusterSecurityGroupId pulumi.StringOutput `pulumi:"clusterSecurityGroupId"` // The EKS cluster and its dependencies. Core CoreDataOutput `pulumi:"core"` // The default Node Group configuration, or undefined if `skipDefaultNodeGroup` was specified. DefaultNodeGroup NodeGroupDataPtrOutput `pulumi:"defaultNodeGroup"` + // The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. + DefaultNodeGroupAsgName pulumi.StringOutput `pulumi:"defaultNodeGroupAsgName"` // The EKS cluster. EksCluster eks.ClusterOutput `pulumi:"eksCluster"` // The ingress rule that gives node group access to cluster API server. EksClusterIngressRule ec2.SecurityGroupRuleOutput `pulumi:"eksClusterIngressRule"` + // The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + FargateProfileId pulumi.StringOutput `pulumi:"fargateProfileId"` + // The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + FargateProfileStatus pulumi.StringOutput `pulumi:"fargateProfileStatus"` // The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. InstanceRoles iam.RoleArrayOutput `pulumi:"instanceRoles"` // A kubeconfig that can be used to connect to the EKS cluster. @@ -70,6 +80,16 @@ type Cluster struct { KubeconfigJson pulumi.StringOutput `pulumi:"kubeconfigJson"` // The security group for the cluster's nodes. NodeSecurityGroup ec2.SecurityGroupOutput `pulumi:"nodeSecurityGroup"` + // The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + NodeSecurityGroupId pulumi.StringOutput `pulumi:"nodeSecurityGroupId"` + // The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). + // + // This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. + OidcIssuer pulumi.StringOutput `pulumi:"oidcIssuer"` + // The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. + OidcProviderArn pulumi.StringOutput `pulumi:"oidcProviderArn"` + // Issuer URL for the OpenID Connect identity provider of the EKS cluster. + OidcProviderUrl pulumi.StringOutput `pulumi:"oidcProviderUrl"` } // NewCluster registers a new resource with the given unique name, arguments, and options. @@ -719,11 +739,21 @@ func (o ClusterOutput) AwsProvider() aws.ProviderOutput { return o.ApplyT(func(v *Cluster) aws.ProviderOutput { return v.AwsProvider }).(aws.ProviderOutput) } +// The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. +func (o ClusterOutput) ClusterIngressRuleId() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.ClusterIngressRuleId }).(pulumi.StringOutput) +} + // The security group for the EKS cluster. func (o ClusterOutput) ClusterSecurityGroup() ec2.SecurityGroupOutput { return o.ApplyT(func(v *Cluster) ec2.SecurityGroupOutput { return v.ClusterSecurityGroup }).(ec2.SecurityGroupOutput) } +// The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. +func (o ClusterOutput) ClusterSecurityGroupId() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.ClusterSecurityGroupId }).(pulumi.StringOutput) +} + // The EKS cluster and its dependencies. func (o ClusterOutput) Core() CoreDataOutput { return o.ApplyT(func(v *Cluster) CoreDataOutput { return v.Core }).(CoreDataOutput) @@ -734,6 +764,11 @@ func (o ClusterOutput) DefaultNodeGroup() NodeGroupDataPtrOutput { return o.ApplyT(func(v *Cluster) NodeGroupDataPtrOutput { return v.DefaultNodeGroup }).(NodeGroupDataPtrOutput) } +// The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. +func (o ClusterOutput) DefaultNodeGroupAsgName() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.DefaultNodeGroupAsgName }).(pulumi.StringOutput) +} + // The EKS cluster. func (o ClusterOutput) EksCluster() eks.ClusterOutput { return o.ApplyT(func(v *Cluster) eks.ClusterOutput { return v.EksCluster }).(eks.ClusterOutput) @@ -744,6 +779,16 @@ func (o ClusterOutput) EksClusterIngressRule() ec2.SecurityGroupRuleOutput { return o.ApplyT(func(v *Cluster) ec2.SecurityGroupRuleOutput { return v.EksClusterIngressRule }).(ec2.SecurityGroupRuleOutput) } +// The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. +func (o ClusterOutput) FargateProfileId() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.FargateProfileId }).(pulumi.StringOutput) +} + +// The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. +func (o ClusterOutput) FargateProfileStatus() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.FargateProfileStatus }).(pulumi.StringOutput) +} + // The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. func (o ClusterOutput) InstanceRoles() iam.RoleArrayOutput { return o.ApplyT(func(v *Cluster) iam.RoleArrayOutput { return v.InstanceRoles }).(iam.RoleArrayOutput) @@ -764,6 +809,28 @@ func (o ClusterOutput) NodeSecurityGroup() ec2.SecurityGroupOutput { return o.ApplyT(func(v *Cluster) ec2.SecurityGroupOutput { return v.NodeSecurityGroup }).(ec2.SecurityGroupOutput) } +// The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. +func (o ClusterOutput) NodeSecurityGroupId() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.NodeSecurityGroupId }).(pulumi.StringOutput) +} + +// The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). +// +// This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. +func (o ClusterOutput) OidcIssuer() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.OidcIssuer }).(pulumi.StringOutput) +} + +// The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. +func (o ClusterOutput) OidcProviderArn() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.OidcProviderArn }).(pulumi.StringOutput) +} + +// Issuer URL for the OpenID Connect identity provider of the EKS cluster. +func (o ClusterOutput) OidcProviderUrl() pulumi.StringOutput { + return o.ApplyT(func(v *Cluster) pulumi.StringOutput { return v.OidcProviderUrl }).(pulumi.StringOutput) +} + type ClusterArrayOutput struct{ *pulumi.OutputState } func (ClusterArrayOutput) ElementType() reflect.Type { diff --git a/sdk/go/eks/vpcCniAddon.go b/sdk/go/eks/vpcCniAddon.go index 6efb1b944..fd4a529dc 100644 --- a/sdk/go/eks/vpcCniAddon.go +++ b/sdk/go/eks/vpcCniAddon.go @@ -15,7 +15,7 @@ import ( // VpcCniAddon manages the configuration of the Amazon VPC CNI plugin for Kubernetes by leveraging the EKS managed add-on. // For more information see: https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html type VpcCniAddon struct { - pulumi.CustomResourceState + pulumi.ResourceState } // NewVpcCniAddon registers a new resource with the given unique name, arguments, and options. @@ -44,36 +44,13 @@ func NewVpcCniAddon(ctx *pulumi.Context, opts = append(opts, aliases) opts = utilities.PkgResourceDefaultOpts(opts) var resource VpcCniAddon - err := ctx.RegisterResource("eks:index:VpcCniAddon", name, args, &resource, opts...) + err := ctx.RegisterRemoteComponentResource("eks:index:VpcCniAddon", name, args, &resource, opts...) if err != nil { return nil, err } return &resource, nil } -// GetVpcCniAddon gets an existing VpcCniAddon resource's state with the given name, ID, and optional -// state properties that are used to uniquely qualify the lookup (nil if not required). -func GetVpcCniAddon(ctx *pulumi.Context, - name string, id pulumi.IDInput, state *VpcCniAddonState, opts ...pulumi.ResourceOption) (*VpcCniAddon, error) { - var resource VpcCniAddon - err := ctx.ReadResource("eks:index:VpcCniAddon", name, id, state, &resource, opts...) - if err != nil { - return nil, err - } - return &resource, nil -} - -// Input properties used for looking up and filtering VpcCniAddon resources. -type vpcCniAddonState struct { -} - -type VpcCniAddonState struct { -} - -func (VpcCniAddonState) ElementType() reflect.Type { - return reflect.TypeOf((*vpcCniAddonState)(nil)).Elem() -} - type vpcCniAddonArgs struct { // The version of the addon to use. If not specified, the latest version of the addon for the cluster's Kubernetes version will be used. AddonVersion *string `pulumi:"addonVersion"` 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 de4b821f7..e9d44aca6 100644 --- a/sdk/java/src/main/java/com/pulumi/eks/Cluster.java +++ b/sdk/java/src/main/java/com/pulumi/eks/Cluster.java @@ -77,6 +77,20 @@ public class Cluster extends com.pulumi.resources.ComponentResource { public Output awsProvider() { return this.awsProvider; } + /** + * The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. + * + */ + @Export(name="clusterIngressRuleId", refs={String.class}, tree="[0]") + private Output clusterIngressRuleId; + + /** + * @return The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. + * + */ + public Output clusterIngressRuleId() { + return this.clusterIngressRuleId; + } /** * The security group for the EKS cluster. * @@ -91,6 +105,20 @@ public Output awsProvider() { public Output> clusterSecurityGroup() { return Codegen.optional(this.clusterSecurityGroup); } + /** + * The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + * + */ + @Export(name="clusterSecurityGroupId", refs={String.class}, tree="[0]") + private Output clusterSecurityGroupId; + + /** + * @return The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + * + */ + public Output clusterSecurityGroupId() { + return this.clusterSecurityGroupId; + } /** * The EKS cluster and its dependencies. * @@ -119,6 +147,20 @@ public Output core() { public Output> defaultNodeGroup() { return Codegen.optional(this.defaultNodeGroup); } + /** + * The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. + * + */ + @Export(name="defaultNodeGroupAsgName", refs={String.class}, tree="[0]") + private Output defaultNodeGroupAsgName; + + /** + * @return The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. + * + */ + public Output defaultNodeGroupAsgName() { + return this.defaultNodeGroupAsgName; + } /** * The EKS cluster. * @@ -147,6 +189,34 @@ public Output eksCluster() { public Output> eksClusterIngressRule() { return Codegen.optional(this.eksClusterIngressRule); } + /** + * The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + * + */ + @Export(name="fargateProfileId", refs={String.class}, tree="[0]") + private Output fargateProfileId; + + /** + * @return The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + * + */ + public Output fargateProfileId() { + return this.fargateProfileId; + } + /** + * The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + * + */ + @Export(name="fargateProfileStatus", refs={String.class}, tree="[0]") + private Output fargateProfileStatus; + + /** + * @return The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + * + */ + public Output fargateProfileStatus() { + return this.fargateProfileStatus; + } /** * The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. * @@ -203,6 +273,66 @@ public Output kubeconfigJson() { public Output> nodeSecurityGroup() { return Codegen.optional(this.nodeSecurityGroup); } + /** + * The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + * + */ + @Export(name="nodeSecurityGroupId", refs={String.class}, tree="[0]") + private Output nodeSecurityGroupId; + + /** + * @return The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + * + */ + public Output nodeSecurityGroupId() { + return this.nodeSecurityGroupId; + } + /** + * The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). + * + * This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. + * + */ + @Export(name="oidcIssuer", refs={String.class}, tree="[0]") + private Output oidcIssuer; + + /** + * @return The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). + * + * This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. + * + */ + public Output oidcIssuer() { + return this.oidcIssuer; + } + /** + * The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. + * + */ + @Export(name="oidcProviderArn", refs={String.class}, tree="[0]") + private Output oidcProviderArn; + + /** + * @return The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. + * + */ + public Output oidcProviderArn() { + return this.oidcProviderArn; + } + /** + * Issuer URL for the OpenID Connect identity provider of the EKS cluster. + * + */ + @Export(name="oidcProviderUrl", refs={String.class}, tree="[0]") + private Output oidcProviderUrl; + + /** + * @return Issuer URL for the OpenID Connect identity provider of the EKS cluster. + * + */ + public Output oidcProviderUrl() { + return this.oidcProviderUrl; + } /** * diff --git a/sdk/java/src/main/java/com/pulumi/eks/VpcCniAddon.java b/sdk/java/src/main/java/com/pulumi/eks/VpcCniAddon.java index e92403e50..af0beff65 100644 --- a/sdk/java/src/main/java/com/pulumi/eks/VpcCniAddon.java +++ b/sdk/java/src/main/java/com/pulumi/eks/VpcCniAddon.java @@ -18,7 +18,7 @@ * */ @ResourceType(type="eks:index:VpcCniAddon") -public class VpcCniAddon extends com.pulumi.resources.CustomResource { +public class VpcCniAddon extends com.pulumi.resources.ComponentResource { /** * * @param name The _unique_ name of the resulting resource. @@ -40,40 +40,25 @@ public VpcCniAddon(java.lang.String name, VpcCniAddonArgs args) { * @param args The arguments to use to populate this resource's properties. * @param options A bag of options that control this resource's behavior. */ - public VpcCniAddon(java.lang.String name, VpcCniAddonArgs args, @Nullable com.pulumi.resources.CustomResourceOptions options) { - super("eks:index:VpcCniAddon", name, makeArgs(args, options), makeResourceOptions(options, Codegen.empty()), false); + public VpcCniAddon(java.lang.String name, VpcCniAddonArgs args, @Nullable com.pulumi.resources.ComponentResourceOptions options) { + super("eks:index:VpcCniAddon", name, makeArgs(args, options), makeResourceOptions(options, Codegen.empty()), true); } - private VpcCniAddon(java.lang.String name, Output id, @Nullable com.pulumi.resources.CustomResourceOptions options) { - super("eks:index:VpcCniAddon", name, null, makeResourceOptions(options, id), false); - } - - private static VpcCniAddonArgs makeArgs(VpcCniAddonArgs args, @Nullable com.pulumi.resources.CustomResourceOptions options) { + private static VpcCniAddonArgs makeArgs(VpcCniAddonArgs args, @Nullable com.pulumi.resources.ComponentResourceOptions options) { if (options != null && options.getUrn().isPresent()) { return null; } return args == null ? VpcCniAddonArgs.Empty : args; } - private static com.pulumi.resources.CustomResourceOptions makeResourceOptions(@Nullable com.pulumi.resources.CustomResourceOptions options, @Nullable Output id) { - var defaultOptions = com.pulumi.resources.CustomResourceOptions.builder() + private static com.pulumi.resources.ComponentResourceOptions makeResourceOptions(@Nullable com.pulumi.resources.ComponentResourceOptions options, @Nullable Output id) { + var defaultOptions = com.pulumi.resources.ComponentResourceOptions.builder() .version(Utilities.getVersion()) .aliases(List.of( Output.of(Alias.builder().type("eks:index:VpcCni").build()) )) .build(); - return com.pulumi.resources.CustomResourceOptions.merge(defaultOptions, options, id); + return com.pulumi.resources.ComponentResourceOptions.merge(defaultOptions, options, id); } - /** - * Get an existing Host resource's state with the given name, ID, and optional extra - * properties used to qualify the lookup. - * - * @param name The _unique_ name of the resulting resource. - * @param id The _unique_ provider ID of the resource to lookup. - * @param options Optional settings to control the behavior of the CustomResource. - */ - public static VpcCniAddon get(java.lang.String name, Output id, @Nullable com.pulumi.resources.CustomResourceOptions options) { - return new VpcCniAddon(name, id, options); - } } diff --git a/sdk/nodejs/cluster.ts b/sdk/nodejs/cluster.ts index e0a8991fb..11d35a617 100644 --- a/sdk/nodejs/cluster.ts +++ b/sdk/nodejs/cluster.ts @@ -51,10 +51,18 @@ export class Cluster extends pulumi.ComponentResource { * The AWS resource provider. */ public /*out*/ readonly awsProvider!: pulumi.Output; + /** + * The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. + */ + public /*out*/ readonly clusterIngressRuleId!: pulumi.Output; /** * The security group for the EKS cluster. */ public readonly clusterSecurityGroup!: pulumi.Output; + /** + * The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + */ + public /*out*/ readonly clusterSecurityGroupId!: pulumi.Output; /** * The EKS cluster and its dependencies. */ @@ -63,6 +71,10 @@ export class Cluster extends pulumi.ComponentResource { * The default Node Group configuration, or undefined if `skipDefaultNodeGroup` was specified. */ public /*out*/ readonly defaultNodeGroup!: pulumi.Output; + /** + * The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. + */ + public /*out*/ readonly defaultNodeGroupAsgName!: pulumi.Output; /** * The EKS cluster. */ @@ -71,6 +83,14 @@ export class Cluster extends pulumi.ComponentResource { * The ingress rule that gives node group access to cluster API server. */ public /*out*/ readonly eksClusterIngressRule!: pulumi.Output; + /** + * The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + */ + public /*out*/ readonly fargateProfileId!: pulumi.Output; + /** + * The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + */ + public /*out*/ readonly fargateProfileStatus!: pulumi.Output; /** * The service roles used by the EKS cluster. Only supported with authentication mode `CONFIG_MAP` or `API_AND_CONFIG_MAP`. */ @@ -87,6 +107,24 @@ export class Cluster extends pulumi.ComponentResource { * The security group for the cluster's nodes. */ public /*out*/ readonly nodeSecurityGroup!: pulumi.Output; + /** + * The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + */ + public /*out*/ readonly nodeSecurityGroupId!: pulumi.Output; + /** + * The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). + * + * This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. + */ + public /*out*/ readonly oidcIssuer!: pulumi.Output; + /** + * The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. + */ + public /*out*/ readonly oidcProviderArn!: pulumi.Output; + /** + * Issuer URL for the OpenID Connect identity provider of the EKS cluster. + */ + public /*out*/ readonly oidcProviderUrl!: pulumi.Output; /** * Create a Cluster resource with the given unique name, arguments, and options. @@ -153,24 +191,42 @@ export class Cluster extends pulumi.ComponentResource { resourceInputs["vpcCniOptions"] = args ? (args.vpcCniOptions ? inputs.vpcCniOptionsArgsProvideDefaults(args.vpcCniOptions) : undefined) : undefined; resourceInputs["vpcId"] = args ? args.vpcId : undefined; resourceInputs["awsProvider"] = undefined /*out*/; + resourceInputs["clusterIngressRuleId"] = undefined /*out*/; + resourceInputs["clusterSecurityGroupId"] = undefined /*out*/; resourceInputs["core"] = undefined /*out*/; resourceInputs["defaultNodeGroup"] = undefined /*out*/; + resourceInputs["defaultNodeGroupAsgName"] = undefined /*out*/; resourceInputs["eksCluster"] = undefined /*out*/; resourceInputs["eksClusterIngressRule"] = undefined /*out*/; + resourceInputs["fargateProfileId"] = undefined /*out*/; + resourceInputs["fargateProfileStatus"] = undefined /*out*/; resourceInputs["kubeconfig"] = undefined /*out*/; resourceInputs["kubeconfigJson"] = undefined /*out*/; resourceInputs["nodeSecurityGroup"] = undefined /*out*/; + resourceInputs["nodeSecurityGroupId"] = undefined /*out*/; + resourceInputs["oidcIssuer"] = undefined /*out*/; + resourceInputs["oidcProviderArn"] = undefined /*out*/; + resourceInputs["oidcProviderUrl"] = undefined /*out*/; } else { resourceInputs["awsProvider"] = undefined /*out*/; + resourceInputs["clusterIngressRuleId"] = undefined /*out*/; resourceInputs["clusterSecurityGroup"] = undefined /*out*/; + resourceInputs["clusterSecurityGroupId"] = undefined /*out*/; resourceInputs["core"] = undefined /*out*/; resourceInputs["defaultNodeGroup"] = undefined /*out*/; + resourceInputs["defaultNodeGroupAsgName"] = undefined /*out*/; resourceInputs["eksCluster"] = undefined /*out*/; resourceInputs["eksClusterIngressRule"] = undefined /*out*/; + resourceInputs["fargateProfileId"] = undefined /*out*/; + resourceInputs["fargateProfileStatus"] = undefined /*out*/; resourceInputs["instanceRoles"] = undefined /*out*/; resourceInputs["kubeconfig"] = undefined /*out*/; resourceInputs["kubeconfigJson"] = undefined /*out*/; resourceInputs["nodeSecurityGroup"] = undefined /*out*/; + resourceInputs["nodeSecurityGroupId"] = undefined /*out*/; + resourceInputs["oidcIssuer"] = undefined /*out*/; + resourceInputs["oidcProviderArn"] = undefined /*out*/; + resourceInputs["oidcProviderUrl"] = undefined /*out*/; } opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts); super(Cluster.__pulumiType, name, resourceInputs, opts, true /*remote*/); diff --git a/sdk/nodejs/vpcCniAddon.ts b/sdk/nodejs/vpcCniAddon.ts index e744f649e..f5bc07197 100644 --- a/sdk/nodejs/vpcCniAddon.ts +++ b/sdk/nodejs/vpcCniAddon.ts @@ -11,19 +11,7 @@ import * as utilities from "./utilities"; * VpcCniAddon manages the configuration of the Amazon VPC CNI plugin for Kubernetes by leveraging the EKS managed add-on. * For more information see: https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html */ -export class VpcCniAddon extends pulumi.CustomResource { - /** - * Get an existing VpcCniAddon resource's state with the given name, ID, and optional extra - * properties used to qualify the lookup. - * - * @param name The _unique_ name of the resulting resource. - * @param id The _unique_ provider ID of the resource to lookup. - * @param opts Optional settings to control the behavior of the CustomResource. - */ - public static get(name: string, id: pulumi.Input, opts?: pulumi.CustomResourceOptions): VpcCniAddon { - return new VpcCniAddon(name, undefined as any, { ...opts, id: id }); - } - +export class VpcCniAddon extends pulumi.ComponentResource { /** @internal */ public static readonly __pulumiType = 'eks:index:VpcCniAddon'; @@ -46,7 +34,7 @@ export class VpcCniAddon extends pulumi.CustomResource { * @param args The arguments to use to populate this resource's properties. * @param opts A bag of options that control this resource's behavior. */ - constructor(name: string, args: VpcCniAddonArgs, opts?: pulumi.CustomResourceOptions) { + constructor(name: string, args: VpcCniAddonArgs, opts?: pulumi.ComponentResourceOptions) { let resourceInputs: pulumi.Inputs = {}; opts = opts || {}; if (!opts.id) { @@ -85,7 +73,7 @@ export class VpcCniAddon extends pulumi.CustomResource { opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts); const aliasOpts = { aliases: [{ type: "eks:index:VpcCni" }] }; opts = pulumi.mergeOptions(opts, aliasOpts); - super(VpcCniAddon.__pulumiType, name, resourceInputs, opts); + super(VpcCniAddon.__pulumiType, name, resourceInputs, opts, true /*remote*/); } } diff --git a/sdk/python/pulumi_eks/cluster.py b/sdk/python/pulumi_eks/cluster.py index d71c891c9..a7519842b 100644 --- a/sdk/python/pulumi_eks/cluster.py +++ b/sdk/python/pulumi_eks/cluster.py @@ -1552,13 +1552,22 @@ def _internal_init(__self__, __props__.__dict__["vpc_cni_options"] = vpc_cni_options __props__.__dict__["vpc_id"] = vpc_id __props__.__dict__["aws_provider"] = None + __props__.__dict__["cluster_ingress_rule_id"] = None + __props__.__dict__["cluster_security_group_id"] = None __props__.__dict__["core"] = None __props__.__dict__["default_node_group"] = None + __props__.__dict__["default_node_group_asg_name"] = None __props__.__dict__["eks_cluster"] = None __props__.__dict__["eks_cluster_ingress_rule"] = None + __props__.__dict__["fargate_profile_id"] = None + __props__.__dict__["fargate_profile_status"] = None __props__.__dict__["kubeconfig"] = None __props__.__dict__["kubeconfig_json"] = None __props__.__dict__["node_security_group"] = None + __props__.__dict__["node_security_group_id"] = None + __props__.__dict__["oidc_issuer"] = None + __props__.__dict__["oidc_provider_arn"] = None + __props__.__dict__["oidc_provider_url"] = None super(Cluster, __self__).__init__( 'eks:index:Cluster', resource_name, @@ -1574,6 +1583,14 @@ def aws_provider(self) -> pulumi.Output['pulumi_aws.Provider']: """ return pulumi.get(self, "aws_provider") + @property + @pulumi.getter(name="clusterIngressRuleId") + def cluster_ingress_rule_id(self) -> pulumi.Output[str]: + """ + The ID of the security group rule that gives node group access to the cluster API server. Defaults to an empty string if `skipDefaultSecurityGroups` is set to true. + """ + return pulumi.get(self, "cluster_ingress_rule_id") + @property @pulumi.getter(name="clusterSecurityGroup") def cluster_security_group(self) -> pulumi.Output[Optional['pulumi_aws.ec2.SecurityGroup']]: @@ -1582,6 +1599,14 @@ def cluster_security_group(self) -> pulumi.Output[Optional['pulumi_aws.ec2.Secur """ return pulumi.get(self, "cluster_security_group") + @property + @pulumi.getter(name="clusterSecurityGroupId") + def cluster_security_group_id(self) -> pulumi.Output[str]: + """ + The cluster security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + """ + return pulumi.get(self, "cluster_security_group_id") + @property @pulumi.getter def core(self) -> pulumi.Output['outputs.CoreData']: @@ -1598,6 +1623,14 @@ def default_node_group(self) -> pulumi.Output[Optional['outputs.NodeGroupData']] """ return pulumi.get(self, "default_node_group") + @property + @pulumi.getter(name="defaultNodeGroupAsgName") + def default_node_group_asg_name(self) -> pulumi.Output[str]: + """ + The name of the default node group's AutoScaling Group. Defaults to an empty string if `skipDefaultNodeGroup` is set to true. + """ + return pulumi.get(self, "default_node_group_asg_name") + @property @pulumi.getter(name="eksCluster") def eks_cluster(self) -> pulumi.Output['pulumi_aws.eks.Cluster']: @@ -1614,6 +1647,22 @@ def eks_cluster_ingress_rule(self) -> pulumi.Output[Optional['pulumi_aws.ec2.Sec """ return pulumi.get(self, "eks_cluster_ingress_rule") + @property + @pulumi.getter(name="fargateProfileId") + def fargate_profile_id(self) -> pulumi.Output[str]: + """ + The ID of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + """ + return pulumi.get(self, "fargate_profile_id") + + @property + @pulumi.getter(name="fargateProfileStatus") + def fargate_profile_status(self) -> pulumi.Output[str]: + """ + The status of the Fargate Profile. Defaults to an empty string if no Fargate profile is configured. + """ + return pulumi.get(self, "fargate_profile_status") + @property @pulumi.getter(name="instanceRoles") def instance_roles(self) -> pulumi.Output[Sequence['pulumi_aws.iam.Role']]: @@ -1646,6 +1695,40 @@ def node_security_group(self) -> pulumi.Output[Optional['pulumi_aws.ec2.Security """ return pulumi.get(self, "node_security_group") + @property + @pulumi.getter(name="nodeSecurityGroupId") + def node_security_group_id(self) -> pulumi.Output[str]: + """ + The node security group ID of the EKS cluster. Returns the EKS created security group if `skipDefaultSecurityGroups` is set to true. + """ + return pulumi.get(self, "node_security_group_id") + + @property + @pulumi.getter(name="oidcIssuer") + def oidc_issuer(self) -> pulumi.Output[str]: + """ + The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`). + + This value can be used to associate kubernetes service accounts with IAM roles. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html. + """ + return pulumi.get(self, "oidc_issuer") + + @property + @pulumi.getter(name="oidcProviderArn") + def oidc_provider_arn(self) -> pulumi.Output[str]: + """ + The ARN of the IAM OpenID Connect Provider for the EKS cluster. Defaults to an empty string if no OIDC provider is configured. + """ + return pulumi.get(self, "oidc_provider_arn") + + @property + @pulumi.getter(name="oidcProviderUrl") + def oidc_provider_url(self) -> pulumi.Output[str]: + """ + Issuer URL for the OpenID Connect identity provider of the EKS cluster. + """ + return pulumi.get(self, "oidc_provider_url") + @pulumi.output_type class GetKubeconfigResult: def __init__(__self__, result=None): diff --git a/sdk/python/pulumi_eks/vpc_cni_addon.py b/sdk/python/pulumi_eks/vpc_cni_addon.py index 331a7d44f..a50cba1cd 100644 --- a/sdk/python/pulumi_eks/vpc_cni_addon.py +++ b/sdk/python/pulumi_eks/vpc_cni_addon.py @@ -516,7 +516,7 @@ def warm_prefix_target(self, value: Optional[pulumi.Input[int]]): pulumi.set(self, "warm_prefix_target", value) -class VpcCniAddon(pulumi.CustomResource): +class VpcCniAddon(pulumi.ComponentResource): @overload def __init__(__self__, resource_name: str, @@ -667,7 +667,9 @@ def _internal_init(__self__, opts = pulumi.ResourceOptions.merge(_utilities.get_resource_opts_defaults(), opts) if not isinstance(opts, pulumi.ResourceOptions): raise TypeError('Expected resource options to be a ResourceOptions instance') - if opts.id is None: + if opts.id is not None: + raise ValueError('ComponentResource classes do not support opts.id') + else: if __props__ is not None: raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource') __props__ = VpcCniAddonArgs.__new__(VpcCniAddonArgs) @@ -711,23 +713,6 @@ def _internal_init(__self__, 'eks:index:VpcCniAddon', resource_name, __props__, - opts) - - @staticmethod - def get(resource_name: str, - id: pulumi.Input[str], - opts: Optional[pulumi.ResourceOptions] = None) -> 'VpcCniAddon': - """ - Get an existing VpcCniAddon resource's state with the given name, id, and optional extra - properties used to qualify the lookup. - - :param str resource_name: The unique name of the resulting resource. - :param pulumi.Input[str] id: The unique provider ID of the resource to lookup. - :param pulumi.ResourceOptions opts: Options for the resource. - """ - opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(id=id)) - - __props__ = VpcCniAddonArgs.__new__(VpcCniAddonArgs) - - return VpcCniAddon(resource_name, opts=opts, __props__=__props__) + opts, + remote=True) From 041a68db6e0344fcfdff22a5d72925d72e8e0175 Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 17:11:45 +0200 Subject: [PATCH 06/10] Fix fargate profile race condition --- nodejs/eks/cluster.ts | 119 +++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/nodejs/eks/cluster.ts b/nodejs/eks/cluster.ts index 577a65e63..95a016fee 100644 --- a/nodejs/eks/cluster.ts +++ b/nodejs/eks/cluster.ts @@ -656,61 +656,6 @@ export function createCore( ); } - const corednsExplicitlyEnabled = - args.corednsAddonOptions?.enabled === true || args.corednsAddonOptions?.configurationValues; - // We can only enable the coredns addon if we have a node group to place it on - // This means we are either using the default node group or the cluster is a fargate cluster - // Also, if the user explicitly enables it then do what they want - pulumi.output(args.fargate).apply((fargate) => { - if ( - corednsExplicitlyEnabled || - ((fargate || !args.skipDefaultNodeGroup) && (args.corednsAddonOptions?.enabled ?? true)) - ) { - const corednsVersion: pulumi.Output = args.corednsAddonOptions?.version - ? pulumi.output(args.corednsAddonOptions.version) - : aws.eks - .getAddonVersionOutput( - { - addonName: "coredns", - kubernetesVersion: eksCluster.version, - mostRecent: true, // whether to return the default version or the most recent version for the specified kubernetes version - }, - { parent, provider }, - ) - .apply((addonVersion) => addonVersion.version); - - const configurationValues = pulumi - .all([args.fargate, args.corednsAddonOptions?.configurationValues]) - .apply(([fargate, configurationValues]) => { - if (fargate) { - return { - computeType: "Fargate", - ...configurationValues, - }; - } else { - return configurationValues; - } - }); - - const corednsAddon = new aws.eks.Addon( - `${name}-coredns`, - { - clusterName: eksCluster.name, - addonName: "coredns", - tags: args.tags, - preserve: true, - addonVersion: corednsVersion, - resolveConflictsOnCreate: - args.corednsAddonOptions?.resolveConflictsOnCreate ?? "OVERWRITE", - resolveConflictsOnUpdate: - args.corednsAddonOptions?.resolveConflictsOnUpdate ?? "OVERWRITE", - configurationValues: stringifyAddonConfiguration(configurationValues), - }, - { parent, provider }, - ); - } - }); - // Instead of using the kubeconfig directly, we also add a wait of up to 5 minutes or until we // can reach the API server for the Output that provides access to the kubeconfig string so that // there is time for the cluster API server to become completely available. Ideally we @@ -1064,6 +1009,70 @@ export function createCore( return result; }); + const corednsExplicitlyEnabled = args.corednsAddonOptions?.enabled === true || args.corednsAddonOptions?.configurationValues; + // We can only enable the coredns addon if we have a node group to place it on + // This means we are either using the default node group or the cluster is a fargate cluster + // Also, if the user explicitly enables it then do what they want + pulumi.output(args.fargate).apply((fargate) => { + if ( + corednsExplicitlyEnabled || + ((fargate || !args.skipDefaultNodeGroup) && (args.corednsAddonOptions?.enabled ?? true)) + ) { + const corednsVersion: pulumi.Output = args.corednsAddonOptions?.version + ? pulumi.output(args.corednsAddonOptions.version) + : aws.eks + .getAddonVersionOutput( + { + addonName: "coredns", + kubernetesVersion: eksCluster.version, + mostRecent: true, // whether to return the default version or the most recent version for the specified kubernetes version + }, + { parent, provider }, + ) + .apply((addonVersion) => addonVersion.version); + + const configurationValues = pulumi + .all([args.fargate, args.corednsAddonOptions?.configurationValues]) + .apply(([fargate, configurationValues]) => { + if (fargate) { + return { + computeType: "Fargate", + ...configurationValues, + }; + } else { + return configurationValues; + } + }); + + const corednsAddon = new aws.eks.Addon( + `${name}-coredns`, + { + clusterName: eksCluster.name, + addonName: "coredns", + tags: args.tags, + preserve: true, + addonVersion: corednsVersion, + resolveConflictsOnCreate: + args.corednsAddonOptions?.resolveConflictsOnCreate ?? "OVERWRITE", + resolveConflictsOnUpdate: + args.corednsAddonOptions?.resolveConflictsOnUpdate ?? "OVERWRITE", + configurationValues: stringifyAddonConfiguration(configurationValues), + }, + { parent, provider, dependsOn: fargateProfile.apply(profile => { + // The coredns addon needs a dependency on the fargate profile because + // if there's no profile at the time of deployment, the pods of the + // addon will be assigned to the default-scheduler and not the + // fargate scheduler. + if (profile) { + return [profile]; + } else { + return []; + } + }) }, + ); + } + }); + // Setup OIDC provider to leverage IAM roles for k8s service accounts. let oidcProvider: aws.iam.OpenIdConnectProvider | undefined; if (args.createOidcProvider) { From 756ceb8787ce08ebc3374180917f1ee407610fc0 Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 17:12:45 +0200 Subject: [PATCH 07/10] Formatting --- nodejs/eks/cluster.ts | 51 +++++++++++++++++++---------- provider/cmd/pulumi-gen-eks/main.go | 2 +- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/nodejs/eks/cluster.ts b/nodejs/eks/cluster.ts index 95a016fee..f7d5e1d97 100644 --- a/nodejs/eks/cluster.ts +++ b/nodejs/eks/cluster.ts @@ -1009,7 +1009,8 @@ export function createCore( return result; }); - const corednsExplicitlyEnabled = args.corednsAddonOptions?.enabled === true || args.corednsAddonOptions?.configurationValues; + const corednsExplicitlyEnabled = + args.corednsAddonOptions?.enabled === true || args.corednsAddonOptions?.configurationValues; // We can only enable the coredns addon if we have a node group to place it on // This means we are either using the default node group or the cluster is a fargate cluster // Also, if the user explicitly enables it then do what they want @@ -1058,17 +1059,21 @@ export function createCore( args.corednsAddonOptions?.resolveConflictsOnUpdate ?? "OVERWRITE", configurationValues: stringifyAddonConfiguration(configurationValues), }, - { parent, provider, dependsOn: fargateProfile.apply(profile => { - // The coredns addon needs a dependency on the fargate profile because - // if there's no profile at the time of deployment, the pods of the - // addon will be assigned to the default-scheduler and not the - // fargate scheduler. - if (profile) { - return [profile]; - } else { - return []; - } - }) }, + { + parent, + provider, + dependsOn: fargateProfile.apply((profile) => { + // The coredns addon needs a dependency on the fargate profile because + // if there's no profile at the time of deployment, the pods of the + // addon will be assigned to the default-scheduler and not the + // fargate scheduler. + if (profile) { + return [profile]; + } else { + return []; + } + }), + }, ); } }); @@ -2092,11 +2097,16 @@ export function createCluster( const kubeconfigJson = pulumi.jsonStringify(core.kubeconfig); - const oidcIssuerUrl = core.cluster.identities.apply(identities => { + const oidcIssuerUrl = core.cluster.identities.apply((identities) => { // this is nowadays guaranteed to be present, but we still check for it to be safe // this was not set for cluster version 1.14 and below. Those versions are not available anymore // since 2020-12-08 and clusters were force upgraded - if (identities && identities.length > 0 && identities[0].oidcs && identities[0].oidcs.length > 0) { + if ( + identities && + identities.length > 0 && + identities[0].oidcs && + identities[0].oidcs.length > 0 + ) { return identities[0].oidcs[0].issuer; } return ""; @@ -2115,17 +2125,22 @@ export function createCluster( kubeconfigJson, // If the cluster is created without default security groups, we're returning the EKS created security group // see: https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html#security-group-default-rules - clusterSecurityGroupId: core.clusterSecurityGroup?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId, + clusterSecurityGroupId: + core.clusterSecurityGroup?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId, nodeSecurityGroupId: nodeSecurityGroup?.id ?? core.cluster.vpcConfig.clusterSecurityGroupId, clusterIngressRuleId: eksClusterIngressRule?.securityGroupRuleId ?? pulumi.output(""), defaultNodeGroupAsgName: defaultNodeGroup?.autoScalingGroup.name ?? pulumi.output(""), - fargateProfileId: core.fargateProfile.apply(fargateProfile => fargateProfile?.id ?? pulumi.output("")), - fargateProfileStatus: core.fargateProfile.apply(fargateProfile => fargateProfile?.status ?? pulumi.output("")), + fargateProfileId: core.fargateProfile.apply( + (fargateProfile) => fargateProfile?.id ?? pulumi.output(""), + ), + fargateProfileStatus: core.fargateProfile.apply( + (fargateProfile) => fargateProfile?.status ?? pulumi.output(""), + ), oidcProviderArn: core.oidcProvider?.arn ?? pulumi.output(""), oidcProviderUrl: oidcIssuerUrl, // The issuer is the issuer URL without the protocol part - oidcIssuer: oidcIssuerUrl.apply(url => url.replace("https://", "")), + oidcIssuer: oidcIssuerUrl.apply((url) => url.replace("https://", "")), }; } diff --git a/provider/cmd/pulumi-gen-eks/main.go b/provider/cmd/pulumi-gen-eks/main.go index 9e68c9771..b6300fc25 100644 --- a/provider/cmd/pulumi-gen-eks/main.go +++ b/provider/cmd/pulumi-gen-eks/main.go @@ -264,7 +264,7 @@ func generateSchema(version semver.Version) schema.PackageSpec { Description: "Issuer URL for the OpenID Connect identity provider of the EKS cluster.", }, "oidcIssuer": { - TypeSpec: schema.TypeSpec{Type: "string"}, + TypeSpec: schema.TypeSpec{Type: "string"}, Description: "The OIDC Issuer of the EKS cluster (OIDC Provider URL without leading `https://`).\n\n" + "This value can be used to associate kubernetes service accounts with IAM roles. For more information, see " + "https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html.", From 8affc6746009c66a31dc74a38e96696eea741808 Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 17:13:01 +0200 Subject: [PATCH 08/10] Add test for scalar types --- examples/examples_nodejs_test.go | 92 +++++++++++++++++++++++ examples/tests/scalar-types/Pulumi.yaml | 3 + examples/tests/scalar-types/iam.ts | 28 +++++++ examples/tests/scalar-types/index.ts | 37 +++++++++ examples/tests/scalar-types/package.json | 13 ++++ examples/tests/scalar-types/tsconfig.json | 24 ++++++ 6 files changed, 197 insertions(+) create mode 100644 examples/tests/scalar-types/Pulumi.yaml create mode 100644 examples/tests/scalar-types/iam.ts create mode 100644 examples/tests/scalar-types/index.ts create mode 100644 examples/tests/scalar-types/package.json create mode 100644 examples/tests/scalar-types/tsconfig.json diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index 70b4c0988..94c7e320a 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -23,6 +23,7 @@ import ( "os/exec" "path" "path/filepath" + "strings" "testing" "time" @@ -1061,3 +1062,94 @@ func TestAccPodSecurityGroups(t *testing.T) { programTestWithExtraOptions(t, &test, nil) } + +func TestAccScalarTypes(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", "scalar-types"), + ExtraRuntimeValidation: func(t *testing.T, info integration.RuntimeValidationStackInfo) { + utils.RunEKSSmokeTest(t, + info.Deployment.Resources, + info.Outputs["kubeconfig1"], + info.Outputs["kubeconfig2"], + ) + + // cluster1 runs the default settings with a default node group and an oidc provider + require.NotNil(t, info.Outputs["cluster1"]) + cluster1 := info.Outputs["cluster1"].(map[string]interface{}) + + require.NotNil(t, cluster1["clusterSecurityGroup"]) + require.NotNil(t, cluster1["nodeSecurityGroup"]) + assert.Equal(t, cluster1["clusterSecurityGroup"].(map[string]interface{})["id"], cluster1["clusterSecurityGroupId"].(string)) + assert.Equal(t, cluster1["nodeSecurityGroup"].(map[string]interface{})["id"], cluster1["nodeSecurityGroupId"].(string)) + assert.NotEmpty(t, cluster1["clusterIngressRuleId"]) + assert.Empty(t, cluster1["fargateProfileId"]) + assert.Empty(t, cluster1["fargateProfileStatus"]) + + require.NotNil(t, cluster1["defaultNodeGroup"]) + defaultNodeGroup1 := cluster1["defaultNodeGroup"].(map[string]interface{}) + assert.Equal(t, defaultNodeGroup1["autoScalingGroup"].(map[string]interface{})["name"], cluster1["defaultNodeGroupAsgName"].(string)) + + require.NotNil(t, cluster1["core"]) + coreData1 := cluster1["core"].(map[string]interface{}) + require.NotNil(t, coreData1["oidcProvider"]) + oidcProvider1 := coreData1["oidcProvider"].(map[string]interface{}) + + assert.Equal(t, oidcProvider1["arn"], cluster1["oidcProviderArn"]) + oidcProviderUrl1 := oidcProvider1["url"].(string) + assert.Equal(t, oidcProvider1["url"], cluster1["oidcProviderUrl"]) + assert.Equal(t, strings.ReplaceAll(oidcProviderUrl1, "https://", ""), cluster1["oidcIssuer"], + "expected oidcIssuer to be the same as the oidcProvider url without the https:// prefix") + + // cluster2 runs with fargate, no default node group, no default security groups and no oidc provider + require.NotNil(t, info.Outputs["cluster2"]) + cluster2 := info.Outputs["cluster2"].(map[string]interface{}) + require.NotNil(t, cluster2["eksCluster"]) + eksCluster := cluster2["eksCluster"].(map[string]interface{}) + require.NotNil(t, eksCluster["vpcConfig"]) + vpcConfig := eksCluster["vpcConfig"].(map[string]interface{}) + + // AWS EKS always creates a security group for the cluster + eksSecurityGroupId := vpcConfig["clusterSecurityGroupId"] + require.NotEmpty(t, eksSecurityGroupId) + + // verify that the cluster and node security group ID are set to the eks security group ID + assert.Equal(t, eksSecurityGroupId, cluster2["clusterSecurityGroupId"]) + assert.Equal(t, eksSecurityGroupId, cluster2["nodeSecurityGroupId"]) + + // verify that the provider creates no security groups + assert.Nil(t, cluster2["clusterSecurityGroup"]) + assert.Nil(t, cluster2["nodeSecurityGroup"]) + assert.Empty(t, cluster2["clusterIngressRuleId"]) + + // verify that the provider creates no default node group + assert.Nil(t, cluster2["defaultNodeGroup"]) + assert.Empty(t, cluster2["defaultNodeGroupAsgName"]) + + require.NotNil(t, cluster2["core"]) + coreData2 := cluster2["core"].(map[string]interface{}) + + // verify that the provider creates no IAM OIDC provider + assert.Empty(t, cluster2["oidcProviderArn"]) + assert.Nil(t, coreData2["oidcProvider"]) + + // every EKS cluster has an OIDC provider URL, even if no OIDC provider is created + oidcProviderUrl2 := cluster2["oidcProviderUrl"].(string) + assert.NotEmpty(t, oidcProviderUrl2) + assert.NotEmpty(t, cluster2["oidcIssuer"]) + assert.Equal(t, strings.ReplaceAll(oidcProviderUrl2, "https://", ""), cluster2["oidcIssuer"], + "expected oidcIssuer to be the same as the oidcProvider url without the https:// prefix") + + // verify that the provider creates a fargate profile + require.NotNil(t, coreData2["fargateProfile"]) + fargateProfile := coreData2["fargateProfile"].(map[string]interface{}) + assert.Equal(t, fargateProfile["id"], cluster2["fargateProfileId"]) + assert.Equal(t, fargateProfile["status"], cluster2["fargateProfileStatus"]) + }, + }) + + programTestWithExtraOptions(t, &test, nil) +} diff --git a/examples/tests/scalar-types/Pulumi.yaml b/examples/tests/scalar-types/Pulumi.yaml new file mode 100644 index 000000000..7a13e6ed2 --- /dev/null +++ b/examples/tests/scalar-types/Pulumi.yaml @@ -0,0 +1,3 @@ +name: scalar-types +description: Tests retrieving the scalar properties of EKS clusters +runtime: nodejs diff --git a/examples/tests/scalar-types/iam.ts b/examples/tests/scalar-types/iam.ts new file mode 100644 index 000000000..214f5bfc0 --- /dev/null +++ b/examples/tests/scalar-types/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/scalar-types/index.ts b/examples/tests/scalar-types/index.ts new file mode 100644 index 000000000..a2e314306 --- /dev/null +++ b/examples/tests/scalar-types/index.ts @@ -0,0 +1,37 @@ + +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; +import * as awsx from "@pulumi/awsx"; +import * as eks from "@pulumi/eks"; +import * as iam from "./iam"; + +const role1 = iam.createRole("scalar-types-1"); +const role2 = iam.createRole("scalar-types-2"); + +const eksVpc = new awsx.ec2.Vpc("scalar-types", { + enableDnsHostnames: true, + cidrBlock: "10.0.0.0/16", +}); + +export const cluster1 = new eks.Cluster("scalar-types-1", { + vpcId: eksVpc.vpcId, + authenticationMode: eks.AuthenticationMode.Api, + publicSubnetIds: eksVpc.publicSubnetIds, + privateSubnetIds: eksVpc.privateSubnetIds, + createOidcProvider: true, +}); + +export const kubeconfig1 = cluster1.kubeconfig; + +export const cluster2 = new eks.Cluster("scalar-types-2", { + vpcId: eksVpc.vpcId, + authenticationMode: eks.AuthenticationMode.Api, + fargate: { + selectors: [{ namespace: "kube-system" }], + }, + skipDefaultSecurityGroups: true, + publicSubnetIds: eksVpc.publicSubnetIds, + privateSubnetIds: eksVpc.privateSubnetIds, +}); + +export const kubeconfig2 = cluster2.kubeconfig; diff --git a/examples/tests/scalar-types/package.json b/examples/tests/scalar-types/package.json new file mode 100644 index 000000000..38effac2f --- /dev/null +++ b/examples/tests/scalar-types/package.json @@ -0,0 +1,13 @@ +{ + "name": "scalar-types", + "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/scalar-types/tsconfig.json b/examples/tests/scalar-types/tsconfig.json new file mode 100644 index 000000000..2ea71672d --- /dev/null +++ b/examples/tests/scalar-types/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" + ] +} From c4cac37f2fd79a8f2792a9baa85fbf09d4aef1eb Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Tue, 15 Oct 2024 17:56:31 +0200 Subject: [PATCH 09/10] Simplify examples --- examples/cluster/index.ts | 2 +- examples/examples_nodejs_test.go | 2 +- examples/extra-sg/index.ts | 4 ++-- examples/oidc-iam-sa/index.ts | 13 +++++-------- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/examples/cluster/index.ts b/examples/cluster/index.ts index 6c0b4675e..66931f50c 100644 --- a/examples/cluster/index.ts +++ b/examples/cluster/index.ts @@ -19,7 +19,7 @@ const cluster1 = new eks.Cluster(`${projectName}-1`, { nodeAmiId: "ami-066e69f6f03b5383e", }); -export const defaultAsgArn: pulumi.Output = cluster1.defaultNodeGroup.apply(ng => ng?.autoScalingGroup.arn ?? pulumi.output("")); +export const defaultAsgName: pulumi.Output = cluster1.defaultNodeGroupAsgName; const cluster2 = new eks.Cluster(`${projectName}-2`, { vpcId: vpc.vpcId, diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index 94c7e320a..a7fd902dd 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -57,7 +57,7 @@ func TestAccCluster(t *testing.T) { info.Outputs["kubeconfig4"], ) - assert.NotEmpty(t, info.Outputs["defaultAsgArn"], "should have a default ASG") + assert.NotEmpty(t, info.Outputs["defaultAsgName"], "should have a default ASG") // let's test there's a iamRoleArn specified for the cluster assert.NotEmpty(t, info.Outputs["iamRoleArn"]) diff --git a/examples/extra-sg/index.ts b/examples/extra-sg/index.ts index 4c717c40b..33c395e6f 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.apply((sg) => sg!.id), + securityGroupId: cluster.nodeSecurityGroupId, sourceSecurityGroupId: customSecurityGroup.id, }); @@ -108,6 +108,6 @@ const ng = new eks.NodeGroupV2("example-mng", { amiId: "ami-066e69f6f03b5383e", extraNodeSecurityGroups: [ customSecurityGroup, // Plain type - cluster.nodeSecurityGroup.apply(sg => sg!), // Input type + cluster.nodeSecurityGroupId, // Input type ], }); diff --git a/examples/oidc-iam-sa/index.ts b/examples/oidc-iam-sa/index.ts index dc9754121..4671d166f 100644 --- a/examples/oidc-iam-sa/index.ts +++ b/examples/oidc-iam-sa/index.ts @@ -19,8 +19,6 @@ export const kubeconfig = cluster.kubeconfig; if (!cluster?.core?.oidcProvider) { throw new Error("Invalid cluster OIDC provider URL"); } -const clusterOidcProvider = cluster.core.oidcProvider; -export const clusterOidcProviderUrl = clusterOidcProvider.apply(u => u!.url); // Setup Pulumi Kubernetes provider. const provider = new k8s.Provider("eks-k8s", { @@ -34,22 +32,21 @@ export const appsNamespaceName = appsNamespace.metadata.name; // Create the new IAM policy for the Service Account using the // AssumeRoleWebWebIdentity action. const saName = "s3"; -const oidcProviderArn = clusterOidcProvider.apply(o => o!.arn); -const saAssumeRolePolicy = pulumi.all([clusterOidcProviderUrl, oidcProviderArn, appsNamespaceName]).apply(([url, arn, namespace]) => aws.iam.getPolicyDocument({ +const saAssumeRolePolicy = aws.iam.getPolicyDocument({ statements: [{ actions: ["sts:AssumeRoleWithWebIdentity"], conditions: [{ test: "StringEquals", - values: [`system:serviceaccount:${namespace}:${saName}`], - variable: `${url.replace("https://", "")}:sub`, + values: [pulumi.interpolate`system:serviceaccount:${appsNamespaceName}:${saName}`], + variable: pulumi.interpolate`${cluster.oidcIssuer}:sub`, }], effect: "Allow", principals: [{ - identifiers: [arn], + identifiers: [cluster.oidcProviderArn], type: "Federated", }], }], -})); +}); const saRole = new aws.iam.Role(saName, { assumeRolePolicy: saAssumeRolePolicy.json, From d81c1ee101d4225a91acb7e826f1433c0a8b29ab Mon Sep 17 00:00:00 2001 From: Florian Stadler Date: Wed, 16 Oct 2024 13:23:11 +0200 Subject: [PATCH 10/10] Fix tests --- examples/examples_nodejs_test.go | 28 +++++++++++++++++++++++----- examples/extra-sg/index.ts | 2 +- examples/oidc-iam-sa/index.ts | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index a7fd902dd..03c7d425e 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -1080,6 +1080,8 @@ func TestAccScalarTypes(t *testing.T) { // cluster1 runs the default settings with a default node group and an oidc provider require.NotNil(t, info.Outputs["cluster1"]) cluster1 := info.Outputs["cluster1"].(map[string]interface{}) + require.NotNil(t, cluster1["eksCluster"]) + eksCluster1 := cluster1["eksCluster"].(map[string]interface{}) require.NotNil(t, cluster1["clusterSecurityGroup"]) require.NotNil(t, cluster1["nodeSecurityGroup"]) @@ -1099,8 +1101,8 @@ func TestAccScalarTypes(t *testing.T) { oidcProvider1 := coreData1["oidcProvider"].(map[string]interface{}) assert.Equal(t, oidcProvider1["arn"], cluster1["oidcProviderArn"]) - oidcProviderUrl1 := oidcProvider1["url"].(string) - assert.Equal(t, oidcProvider1["url"], cluster1["oidcProviderUrl"]) + oidcProviderUrl1 := getOidcProviderUrl(t, eksCluster1) + assert.Equal(t, oidcProviderUrl1, cluster1["oidcProviderUrl"]) assert.Equal(t, strings.ReplaceAll(oidcProviderUrl1, "https://", ""), cluster1["oidcIssuer"], "expected oidcIssuer to be the same as the oidcProvider url without the https:// prefix") @@ -1108,9 +1110,9 @@ func TestAccScalarTypes(t *testing.T) { require.NotNil(t, info.Outputs["cluster2"]) cluster2 := info.Outputs["cluster2"].(map[string]interface{}) require.NotNil(t, cluster2["eksCluster"]) - eksCluster := cluster2["eksCluster"].(map[string]interface{}) - require.NotNil(t, eksCluster["vpcConfig"]) - vpcConfig := eksCluster["vpcConfig"].(map[string]interface{}) + eksCluster2 := cluster2["eksCluster"].(map[string]interface{}) + require.NotNil(t, eksCluster2["vpcConfig"]) + vpcConfig := eksCluster2["vpcConfig"].(map[string]interface{}) // AWS EKS always creates a security group for the cluster eksSecurityGroupId := vpcConfig["clusterSecurityGroupId"] @@ -1153,3 +1155,19 @@ func TestAccScalarTypes(t *testing.T) { programTestWithExtraOptions(t, &test, nil) } + +func getOidcProviderUrl(t *testing.T, eksCluster map[string]interface{}) string { + require.NotEmpty(t, eksCluster["identities"]) + identities := eksCluster["identities"].([]interface{}) + require.NotEmpty(t, identities[0]) + + require.Contains(t, identities[0].(map[string]interface{}), "oidcs") + require.NotEmpty(t, identities[0].(map[string]interface{})["oidcs"]) + oidcs := identities[0].(map[string]interface{})["oidcs"].([]interface{}) + + require.NotEmpty(t, oidcs[0]) + require.Contains(t, oidcs[0].(map[string]interface{}), "issuer") + require.NotEmpty(t, oidcs[0].(map[string]interface{})["issuer"]) + + return oidcs[0].(map[string]interface{})["issuer"].(string) +} diff --git a/examples/extra-sg/index.ts b/examples/extra-sg/index.ts index 33c395e6f..ddc61112e 100644 --- a/examples/extra-sg/index.ts +++ b/examples/extra-sg/index.ts @@ -108,6 +108,6 @@ const ng = new eks.NodeGroupV2("example-mng", { amiId: "ami-066e69f6f03b5383e", extraNodeSecurityGroups: [ customSecurityGroup, // Plain type - cluster.nodeSecurityGroupId, // Input type + cluster.nodeSecurityGroup.apply(sg => sg!), // Input type ], }); diff --git a/examples/oidc-iam-sa/index.ts b/examples/oidc-iam-sa/index.ts index 4671d166f..56a8f1de4 100644 --- a/examples/oidc-iam-sa/index.ts +++ b/examples/oidc-iam-sa/index.ts @@ -32,7 +32,7 @@ export const appsNamespaceName = appsNamespace.metadata.name; // Create the new IAM policy for the Service Account using the // AssumeRoleWebWebIdentity action. const saName = "s3"; -const saAssumeRolePolicy = aws.iam.getPolicyDocument({ +const saAssumeRolePolicy = aws.iam.getPolicyDocumentOutput({ statements: [{ actions: ["sts:AssumeRoleWithWebIdentity"], conditions: [{