Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add eks example test #229

Merged
merged 1 commit into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/aws-eks-example/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: eks-example
runtime:
name: nodejs
options:
packagemanager: npm
19 changes: 19 additions & 0 deletions examples/aws-eks-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# AWS EKS Module Example

## Setup Steps

Install the Terraform modules using `pulumi package add`.

```console
$ yarn install
$ pulumi package add terraform-module terraform-aws-modules/vpc/aws 5.19.0 vpcmod
$ pulumi package add terraform-module terraform-aws-modules/eks/aws 20.34.0 eksmod
```

## Deploy

To deploy the example run

```console
$ pulumi up
```
179 changes: 179 additions & 0 deletions examples/aws-eks-example/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import * as vpcmod from '@pulumi/vpcmod';
import * as k8s from '@pulumi/kubernetes';
import * as pulumi from '@pulumi/pulumi';
import * as eksmod from '@pulumi/eksmod';
import * as aws from '@pulumi/aws';
import * as std from '@pulumi/std';
import { getKubeConfig } from './kube-config';

const azs = aws.getAvailabilityZonesOutput({
filters: [{
name: "opt-in-status",
values: ["opt-in-not-required"],
}]
}).names.apply(names => names.slice(0, 3));

const cidr = "10.0.0.0/16";

const cfg = new pulumi.Config();
const prefix = cfg.get("prefix") ?? pulumi.getStack();

const vpc = new vpcmod.Module("test-vpc", {
azs: azs,
name: `test-vpc-${prefix}`,
cidr,
private_subnets: azs.apply(azs => azs.map((_, i) => {
return getCidrSubnet(cidr, 8, i+1);
})),
public_subnets: azs.apply(azs => azs.map((_, i) => {
return getCidrSubnet(cidr, 8, i+1+4);
})),
intra_subnets: azs.apply(azs => azs.map((_, i) => {
return getCidrSubnet(cidr, 8, i+1 + 8);
})),


enable_nat_gateway: true,
single_nat_gateway: true,

public_subnet_tags: {
'kubernetes.io/role/elb': '1',
},
private_subnet_tags: {
'kubernetes.io/role/internal-elb': '1',
},
});

const cluster = new eksmod.Module('test-cluster', {
cluster_name: `test-cluster-${prefix}`,
cluster_endpoint_public_access: true,
cluster_compute_config: {
enabled: true,
node_pools: ["general-purpose"],
},
vpc_id: vpc.vpc_id.apply(id => id!),
// TODO [pulumi/pulumi-terraform-module#228] have to use a list of unknowns instead of unknown list
subnet_ids: [
vpc.private_subnets.apply(subnets => subnets![0]),
vpc.private_subnets.apply(subnets => subnets![1]),
vpc.private_subnets.apply(subnets => subnets![2]),
],
enable_cluster_creator_admin_permissions: true,
}, { dependsOn: vpc });

// Make the cluster name an output so the downstream resources depend on the cluster creation
const clusterName = pulumi.all([cluster.cluster_arn, cluster.cluster_name]).apply(([_clusterArn, clusterName]) => {
return clusterName!;
});

const kubeconfig = getKubeConfig(clusterName, {
dependsOn: cluster,
});

const k8sProvider = new k8s.Provider("k8sProvider", {
kubeconfig,
}, { dependsOn: cluster });


const appName = "nginx";
const ns = new k8s.core.v1.Namespace(appName, {
metadata: { name: appName },
}, { provider: k8sProvider });

const configMap = new k8s.core.v1.ConfigMap(appName, {
metadata: {
namespace: ns.metadata.name,
},
data: {
"index.html": "<html><body><h1>Hello, Pulumi!</h1></body></html>",
},
}, { provider: k8sProvider });

const deployment = new k8s.apps.v1.Deployment(appName, {
metadata: {
namespace: ns.metadata.name
},
spec: {
selector: { matchLabels: { app: appName } },
replicas: 3,
template: {
metadata: { labels: { app: appName } },
spec: {
containers: [{
name: appName,
image: appName,
ports: [{ containerPort: 80 }],
volumeMounts: [{ name: "nginx-index", mountPath: "/usr/share/nginx/html" }],
}],
volumes: [{
name: "nginx-index",
configMap: { name: configMap.metadata.name },
}],
},
},
},
}, { provider: k8sProvider });

const service = new k8s.core.v1.Service(appName, {
metadata: {
name: appName,
namespace: ns.metadata.name
},
spec: {
selector: { app: appName },
ports: [{ port: 80, targetPort: 80 }],
},
}, { provider: k8sProvider, dependsOn: [deployment] });

const ingressClass = new k8s.networking.v1.IngressClass("alb", {
metadata: {
namespace: ns.metadata.name,
labels: {
"app.kubernetes.io/name": "LoadBalancerController",
},
name: "alb",
},
spec: {
controller: "eks.amazonaws.com/alb",
}
}, { provider: k8sProvider });

const ingress = new k8s.networking.v1.Ingress(appName, {
metadata: {
namespace: ns.metadata.name,
// Annotations for EKS Auto Mode to identify the Ingress as internet-facing and target-type as IP.
annotations: {
"alb.ingress.kubernetes.io/scheme": "internet-facing",
"alb.ingress.kubernetes.io/target-type": "ip",
}
},
spec: {
ingressClassName: ingressClass.metadata.name,
rules: [{
http: {
paths: [{
path: "/",
pathType: "Prefix",
backend: {
service: {
name: service.metadata.name,
port: {
number: 80,
},
},
},
}],
},
}],
}
}, { provider: k8sProvider });

export const url = ingress.status.apply(status => status?.loadBalancer?.ingress?.[0]?.hostname);

function getCidrSubnet(cidr: string, newbits: number, netnum: number): pulumi.Output<string> {
return std.cidrsubnetOutput({
input: cidr,
newbits,
netnum,
}).result
}
64 changes: 64 additions & 0 deletions examples/aws-eks-example/kube-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
function getRegion(opts?: pulumi.InvokeOptions): pulumi.Output<string> {
return pulumi.output(aws.getRegionOutput({}, opts ).name);
}
export function getKubeConfig(
clusterName: pulumi.Input<string>,
opts?: pulumi.InvokeOutputOptions,
): pulumi.Output<string> {
const cluster = aws.eks.getClusterOutput(
{
name: clusterName,
},
);

return pulumi.output(
cluster.certificateAuthorities.apply((certificateAuthorities) => {
return pulumi.jsonStringify({
apiVersion: 'v1',
kind: 'Config',
clusters: [
{
name: cluster.arn,
cluster: {
server: cluster.endpoint,
'certificate-authority-data': certificateAuthorities[0].data,
},
},
],
contexts: [
{
name: cluster.arn,
context: {
user: cluster.arn,
cluster: cluster.arn,
},
},
],
'current-context': cluster.arn,
users: [
{
name: cluster.arn,
user: {
exec: {
apiVersion: 'client.authentication.k8s.io/v1beta1',
args: [
'--region',
getRegion(opts),
'eks',
'get-token',
'--cluster-name',
clusterName,
'--output',
'json',
],
command: 'aws',
},
},
},
],
});
}),
);
}
14 changes: 14 additions & 0 deletions examples/aws-eks-example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "eks-example",
"main": "index.ts",
"devDependencies": {
"@types/node": "^18",
"typescript": "^5.0.0"
},
"dependencies": {
"@pulumi/aws": "^6.72.0",
"@pulumi/kubernetes": "^4.22.1",
"@pulumi/pulumi": "^3.113.0",
"@pulumi/std": "^2.2.0"
}
}
30 changes: 30 additions & 0 deletions tests/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,33 @@ func Test_RdsExample(t *testing.T) {
rdsUrn,
}))
}

func Test_EksExample(t *testing.T) {
localProviderBinPath := ensureCompiledProvider(t)
skipLocalRunsWithoutCreds(t)
// Module written to support the test.
testProgram, err := filepath.Abs(filepath.Join("../", "examples", "aws-eks-example"))
require.NoError(t, err)
localPath := opttest.LocalProviderPath("terraform-module", filepath.Dir(localProviderBinPath))
integrationTest := pulumitest.NewPulumiTest(t, testProgram, localPath)

// Get a prefix for resource names
prefix := generateTestResourcePrefix()

// Set prefix via config
integrationTest.SetConfig(t, "prefix", prefix)

// Generate package
pulumiPackageAdd(t, integrationTest, localProviderBinPath, "terraform-aws-modules/vpc/aws", "5.19.0", "vpcmod")
pulumiPackageAdd(t, integrationTest, localProviderBinPath, "terraform-aws-modules/eks/aws", "20.34.0", "eksmod")

integrationTest.Up(t, optup.Diff(),
optup.ErrorProgressStreams(os.Stderr),
optup.ProgressStreams(os.Stdout),
)

integrationTest.Preview(t, optpreview.Diff(), optpreview.ExpectNoChanges(),
optpreview.ErrorProgressStreams(os.Stderr),
optpreview.ProgressStreams(os.Stdout),
)
}
Loading