├── README.md
├── apps
├── configmap-rollout
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── default.conf
│ ├── images
│ │ ├── rollout.cast
│ │ └── rollout.gif
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── cronjob
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── daemonset
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── deployment-secret
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── job
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── pod-sidecar
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── statefulset
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
└── wordpress
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── aws
├── 01-identity
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 02-managed-infra
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 03-cluster-configuration
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── iam.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 04-cluster-services
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 05-app-services
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
└── 06-apps
│ └── build-deploy-container
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── node-app
│ ├── .dockerignore
│ ├── Dockerfile
│ └── app
│ │ ├── index.html
│ │ ├── index.js
│ │ └── package.json
│ ├── package.json
│ └── tsconfig.json
├── azure
├── 01-identity
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 02-managed-infra
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 03-cluster-configuration
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 04-cluster-services
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 05-app-services
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── mongoHelpers.ts
│ ├── package.json
│ └── tsconfig.json
├── 06-apps
│ └── build-deploy-container
│ │ ├── Pulumi.yaml
│ │ ├── README.md
│ │ ├── config.ts
│ │ ├── index.ts
│ │ ├── node-app
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ └── app
│ │ │ ├── index.html
│ │ │ ├── index.js
│ │ │ └── package.json
│ │ ├── package.json
│ │ └── tsconfig.json
├── identity
│ └── yarn.lock
└── infrastructure
│ └── yarn.lock
├── gcp
├── 01-identity
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── util.ts
├── 02-managed-infra
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── index.ts
│ └── package.json
├── 03-cluster-configuration
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── 04-cluster-services
│ └── README.md
├── 05-app-services
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
└── 06-apps
│ └── build-deploy-container
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── node-app
│ ├── .dockerignore
│ ├── Dockerfile
│ └── app
│ │ ├── index.html
│ │ ├── index.js
│ │ └── package.json
│ ├── package.json
│ └── tsconfig.json
├── general-app-services
└── nginx-ingress-controller
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── general-cluster-services
└── datadog-daemonset
│ ├── Pulumi.yaml
│ ├── README.md
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── tsconfig.json
├── images
└── cake.svg
└── orig
├── README.md
├── aws
├── identity
│ ├── README.md
│ ├── examples
│ │ └── eks-admin
│ │ │ ├── Pulumi.yaml
│ │ │ ├── index.ts
│ │ │ ├── package.json
│ │ │ └── util.ts
│ ├── index.ts
│ ├── lib
│ │ ├── baseline.ts
│ │ ├── common.ts
│ │ ├── groups.ts
│ │ └── policies.ts
│ ├── package.json
│ └── yarn.lock
└── infrastructure
│ ├── Pulumi.yaml
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── scripts
│ └── deploy-with-ci-user.sh
├── azure
├── identity
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── yarn.lock
└── infrastructure
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── yarn.lock
├── docs
├── 00-prerequisites.md
├── 01-architecture.md
├── 02-identity.md
├── 03-infrastructure.md
├── 04-app.md
└── images
│ ├── app.png
│ ├── identity.png
│ ├── infrastructure.png
│ └── kube-arch.png
├── gcp
├── identity
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── util.ts
└── infrastructure
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── config.ts
│ ├── index.ts
│ ├── package.json
│ └── scripts
│ └── login-to-ci-service-account.sh
├── services
├── .gitignore
├── scripts
│ ├── get-kubeconfig.sh
│ └── login-to-ci-service-account.sh
└── wordpress
│ ├── .gitignore
│ ├── Pulumi.yaml
│ ├── config.ts
│ ├── index.ts
│ └── package.json
├── tsconfig.json
└── tslint.json
/README.md:
--------------------------------------------------------------------------------
1 | # Kubernetes Guides
2 |
3 | [Pulumi Crosswalk for Kubernetes][crosswalk-k8s] is a collection of industry standard
4 | best-practices for managing Kubernetes, and its infrastructure in production.
5 |
6 | This guide is for provisioning and configuring production-grade Kubernetes
7 | clusters, and deploying workloads into the clusters.
8 |
9 | If you are just getting started with Pulumi and Kubernetes, the
10 | [Get Started][k8s-get-started] guide is a better place to start.
11 |
12 |
13 |
14 | The cloud provider stacks to deploy.
15 |
16 | | AWS | Azure | GCP |
17 | |---|---|---|
18 | | [Identity](./aws/01-identity) | [Identity](./azure/01-identity) | [Identity](./gcp/01-identity) |
19 | | [Managed Infrastructure](./aws/02-managed-infra) | [Managed Infrastructure](./azure/02-managed-infra) | [Managed Infrastructure](./gcp/02-managed-infra) |
20 | | [Cluster Configuration](./aws/03-cluster-configuration) | [Cluster Configuration](./azure/03-cluster-configuration) | [Cluster Configuration](./gcp/03-cluster-configuration) |
21 | | [Deploy Cluster Services](./aws/04-cluster-services) | [Deploy Cluster Services](./azure/04-cluster-services) | [Deploy Cluster Services](./gcp/04-cluster-services) |
22 | | [Deploy App Services](./aws/05-app-services) | [Deploy App Services](./azure/05-app-services) | [Deploy App Services](./gcp/05-app-services) |
23 | | [Deploy Apps](./aws/06-apps) | [Deploy Apps](./azure/06-apps) | [Deploy Apps](./gcp/06-apps) |
24 |
25 | The Kubernetes stacks that can be deployed on all clouds:
26 |
27 | * [General Cluster Services](./general-cluster-services)
28 | * [General App Services](./general-app-services)
29 | * [Apps](./apps)
30 |
31 | [crosswalk-k8s]: https://pulumi.com/docs/guides/crosswalk/kubernetes
32 | [k8s-get-started]: https://pulumi.com/docs/get-started/kubernetes
33 |
--------------------------------------------------------------------------------
/apps/configmap-rollout/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-configmap-rollout
2 | description: A Deployment that mounts a ConfigMap; updating the data in the ConfigMap triggers a rollout of the Deployment
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/configmap-rollout/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/configmap-rollout/default.conf:
--------------------------------------------------------------------------------
1 | upstream node {
2 | server pulumi.github.io;
3 | }
4 | server {
5 | listen 80;
6 | server_name _;
7 | root /usr/share/nginx/html;
8 | location / {
9 | proxy_set_header X-Real-IP \$remote_addr;
10 | proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
11 | proxy_set_header Host pulumi.github.io;
12 | proxy_pass http://node;
13 | proxy_redirect off;
14 | port_in_redirect off;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/apps/configmap-rollout/images/rollout.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pulumi/kubernetes-guides/a29612928c8082516bac34eb4b57ed2a3cdde9df/apps/configmap-rollout/images/rollout.gif
--------------------------------------------------------------------------------
/apps/configmap-rollout/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as k8s from "@pulumi/kubernetes";
4 | import * as fs from "fs";
5 | import { config } from "./config";
6 |
7 | const provider = new k8s.Provider("provider", {
8 | kubeconfig: config.kubeconfig,
9 | namespace: config.appsNamespaceName,
10 | });
11 |
12 | const appName = "nginx";
13 | const appLabels = { app: appName };
14 |
15 | // nginx Configuration data to proxy traffic to `pulumi.github.io`. Read from
16 | // `default.conf` file.
17 | const nginxConfig = new k8s.core.v1.ConfigMap(appName, {
18 | metadata: { labels: appLabels },
19 | data: { "default.conf": fs.readFileSync("default.conf").toString() },
20 | }, { provider: provider });
21 | const nginxConfigName = nginxConfig.metadata.name;
22 |
23 | // Deploy 1 nginx replica, mounting the configuration data into the nginx
24 | // container.
25 | const nginx = new k8s.apps.v1.Deployment(appName, {
26 | metadata: { labels: appLabels },
27 | spec: {
28 | selector: {
29 | matchLabels: appLabels,
30 | },
31 | replicas: 1,
32 | template: {
33 | metadata: { labels: appLabels },
34 | spec: {
35 | containers: [
36 | {
37 | image: "nginx:1.13.6-alpine",
38 | name: "nginx",
39 | volumeMounts: [{ name: "nginx-configs", mountPath: "/etc/nginx/conf.d" }],
40 | },
41 | ],
42 | volumes: [{ name: "nginx-configs", configMap: { name: nginxConfigName } }],
43 | },
44 | },
45 | },
46 | }, { provider: provider });
47 |
48 | // Expose proxy to the public Internet.
49 | const frontend = new k8s.core.v1.Service(appName, {
50 | metadata: { labels: nginx.spec.template.metadata.labels },
51 | spec: {
52 | type: "LoadBalancer",
53 | ports: [{ port: 80, targetPort: 80, protocol: "TCP" }],
54 | selector: appLabels,
55 | },
56 | }, { provider: provider });
57 |
58 | // Export the frontend IP.
59 | export const frontendIp = frontend.status.loadBalancer.ingress[0].ip;
60 |
--------------------------------------------------------------------------------
/apps/configmap-rollout/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-configmap-rollout",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/configmap-rollout/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/cronjob/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-cronjob
2 | description: Show how to create a CronJob
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/cronjob/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/cronjob/README.md)
2 |
3 | # CronJob
4 |
5 | Create a CronJob that runs a Pod on a schedule.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/cronjob/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/cronjob/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as k8s from "@pulumi/kubernetes";
4 | import { config } from "./config";
5 |
6 | const provider = new k8s.Provider("provider", {
7 | kubeconfig: config.kubeconfig,
8 | namespace: config.appsNamespaceName,
9 | });
10 |
11 | // Create an example CronJob.
12 | const exampleCronJob = new k8s.batch.v1beta1.CronJob("example-cronjob", {
13 | spec: {
14 | schedule: "*/1 * * * *",
15 | jobTemplate: {
16 | spec: {
17 | template: {
18 | spec: {
19 | containers: [
20 | {
21 | name: "hello",
22 | image: "busybox",
23 | args: ["/bin/sh", "-c", "date; echo Hello from the Kubernetes cluster"],
24 | }
25 | ],
26 | restartPolicy: "OnFailure"
27 | }
28 | }
29 | }
30 | },
31 | }
32 | }, { provider: provider });
33 |
--------------------------------------------------------------------------------
/apps/cronjob/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-cronjob",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/cronjob/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/daemonset/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-daemonset
2 | description: Show how to create a DaemonSet
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/daemonset/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/daemonset/README.md)
2 |
3 | # DaemonSet
4 |
5 | Create a DaemonSet that deploys a Pod to each worker node.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/daemonset/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/daemonset/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as k8s from "@pulumi/kubernetes";
4 | import { config } from "./config";
5 |
6 | const provider = new k8s.Provider("provider", {
7 | kubeconfig: config.kubeconfig,
8 | namespace: config.appsNamespaceName,
9 | });
10 |
11 | // Create a DaemonSet that deploys nginx to each worker node.
12 | const appName = "nginx";
13 | const appLabels = { app: appName };
14 | const nginx = new k8s.apps.v1.DaemonSet(appName, {
15 | metadata: { labels: appLabels },
16 | spec: {
17 | selector: {
18 | matchLabels: appLabels,
19 | },
20 | template: {
21 | metadata: { labels: appLabels },
22 | spec: {
23 | containers: [
24 | {
25 | image: "nginx",
26 | name: "nginx",
27 | },
28 | ],
29 | },
30 | },
31 | },
32 | }, { provider: provider });
33 |
--------------------------------------------------------------------------------
/apps/daemonset/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-daemonset",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/daemonset/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/deployment-secret/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-deployment-secret
2 | description: A Deployment that references a secret value as an environment variable.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/deployment-secret/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/deployment-secret/README.md)
2 |
3 | # Deployment Secret
4 |
5 | Inject database credentials into a Deployment as environment variables.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/deployment-secret/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 |
23 | // Misc
24 | databaseUsername: "admin",
25 | databasePassword: "supersecurepassword123",
26 | };
27 |
--------------------------------------------------------------------------------
/apps/deployment-secret/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as k8s from "@pulumi/kubernetes";
4 | import * as kx from "@pulumi/kubernetesx";
5 | import { config } from "./config";
6 |
7 | const provider = new k8s.Provider("provider", {
8 | kubeconfig: config.kubeconfig,
9 | namespace: config.appsNamespaceName,
10 | });
11 |
12 | // Create a Secret with the database credentials.
13 | const databaseSecret = new k8s.core.v1.Secret("db-secret", {
14 | stringData: {
15 | "database-username": config.databaseUsername,
16 | "database-password": config.databasePassword,
17 | }
18 | }, { provider: provider });
19 |
20 | // Create a Deployment that uses the database credentials as environment variables.
21 | const appName = "nginx";
22 | const appLabels = { app: appName };
23 | const nginx = new k8s.apps.v1.Deployment(appName, {
24 | metadata: { labels: appLabels },
25 | spec: {
26 | selector: {
27 | matchLabels: appLabels,
28 | },
29 | replicas: 1,
30 | template: {
31 | metadata: { labels: appLabels },
32 | spec: {
33 | containers: [
34 | {
35 | image: "nginx",
36 | name: "nginx",
37 | env: [
38 | {
39 | name: "DATABASE_USERNAME",
40 | valueFrom: {
41 | secretKeyRef: {
42 | name: databaseSecret.metadata.name,
43 | key: "database-username"
44 | }
45 | }
46 | },
47 | {
48 | name: "DATABASE_PASSWORD",
49 | valueFrom: {
50 | secretKeyRef: {
51 | name: databaseSecret.metadata.name,
52 | key: "database-password"
53 | }
54 | }
55 | }
56 | ]
57 | },
58 | ],
59 | },
60 | },
61 | },
62 | }, { provider: provider });
63 |
64 | //
65 | // Example using KX
66 | //
67 |
68 | // Create a KX Secret with the database credentials.
69 | const databaseSecretKx = new kx.Secret("db-secret", {
70 | stringData: {
71 | "database-username": config.databaseUsername,
72 | "database-password": config.databasePassword,
73 | }
74 | }, { provider: provider });
75 |
76 | // Define the Pod to deploy.
77 | const nginxPB = new kx.PodBuilder({
78 | containers: [{
79 | image: "nginx",
80 | env: {
81 | "DATABASE_USERNAME": databaseSecretKx.asEnvValue("database-username"),
82 | "DATABASE_PASSWORD": databaseSecretKx.asEnvValue("database-password"),
83 | }
84 | }]
85 | });
86 |
87 | // Create a KX Deployment from the KX PodBuilder by transforming it into a DeploymentSpec.
88 | // The deployment uses the database credentials as environment variables.
89 | const nginxKx = new kx.Deployment(appName, {
90 | spec: nginxPB.asDeploymentSpec({replicas: 1})
91 | }, { provider: provider });
92 |
--------------------------------------------------------------------------------
/apps/deployment-secret/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-deployment-secret",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest",
9 | "@pulumi/kubernetesx": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/apps/deployment-secret/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/job/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-job
2 | description: Show how to create a Job
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/job/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/job/README.md)
2 |
3 | # Job
4 |
5 | Create a Job that successfully runs to completion.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/job/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/job/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as k8s from "@pulumi/kubernetes";
4 | import * as kx from "@pulumi/kubernetesx";
5 | import { config } from "./config";
6 |
7 | const provider = new k8s.Provider("provider", {
8 | kubeconfig: config.kubeconfig,
9 | namespace: config.appsNamespaceName,
10 | });
11 |
12 | // Create an example Job.
13 | const exampleJob = new k8s.batch.v1.Job("example-job", {
14 | spec: {
15 | template: {
16 | spec: {
17 | containers: [
18 | {
19 | name: "pi",
20 | image: "perl",
21 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"],
22 | }
23 | ],
24 | restartPolicy: "Never"
25 | }
26 | },
27 | }
28 | }, { provider: provider });
29 |
30 | // Example using kx.
31 |
32 | // Create the PodBuilder for the Job.
33 | const pb = new kx.PodBuilder({
34 | containers: [{
35 | name: "pi",
36 | image: "perl",
37 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"],
38 | }],
39 | restartPolicy: "Never",
40 | });
41 |
42 | // Create a Job using the Pod defined by the PodBuilder.
43 | const exampleJobKx = new kx.Job("example-job-kx", {
44 | spec: pb.asJobSpec(),
45 | }, { provider: provider });
46 |
--------------------------------------------------------------------------------
/apps/job/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-job",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest",
9 | "@pulumi/kubernetesx": "^0.1.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/apps/job/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/pod-sidecar/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-pod-sidecar
2 | description: Create a Pod with a Sidecar container.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/pod-sidecar/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/pod-sidecar/README.md)
2 |
3 | # Pod with a Sidecar
4 |
5 | Create a NGINX Pod with a Debian container sidecar.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/pod-sidecar/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/pod-sidecar/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as k8s from "@pulumi/kubernetes";
4 | import { config } from "./config";
5 |
6 | const provider = new k8s.Provider("provider", {
7 | kubeconfig: config.kubeconfig,
8 | namespace: config.appsNamespaceName,
9 | });
10 |
11 | // Create an example Pod with a Sidecar.
12 | const pod = new k8s.core.v1.Pod("example", {
13 | spec: {
14 | restartPolicy: "Never",
15 | volumes: [
16 | {name: "shared-data", emptyDir: {}},
17 | ],
18 | containers: [
19 | {
20 | name: "nginx",
21 | image: "nginx",
22 | resources: {requests: {cpu: "50m", memory: "50Mi"}},
23 | volumeMounts: [
24 | { name: "shared-data", mountPath: "/usr/share/nginx/html"},
25 | ],
26 | },
27 | {
28 | name: "debian-container",
29 | image: "debian",
30 | resources: {requests: {cpu: "50m", memory: "50Mi"}},
31 | volumeMounts: [
32 | { name: "shared-data", mountPath: "/pod-data"},
33 | ],
34 | command: [ "/bin/bash"],
35 | args: ["-c", "echo Hello from the Debian container > /pod-data/index.html ; sleep infinity"],
36 | }
37 | ],
38 | }
39 | }, { provider: provider });
40 |
--------------------------------------------------------------------------------
/apps/pod-sidecar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-job",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/pod-sidecar/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/apps/statefulset/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-statefulset
2 | description: Show how to create a StatefulSet
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/statefulset/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/statefulset/README.md)
2 |
3 | # StatefulSet
4 |
5 | This example deploys MariaDB as a StatefulSet.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/statefulset/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/statefulset/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-statefulset",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/kubernetes": "latest",
9 | "@pulumi/pulumi": "latest",
10 | "@pulumi/random": "latest"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/apps/statefulset/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/apps/wordpress/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-wordpress
2 | description: Deploy wordpress.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/apps/wordpress/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/apps/wordpress/README.md)
2 |
3 | # Deploy Wordpress
4 |
5 | This example deploys wordpress.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 3. Update the stack.
32 |
33 | ```bash
34 | $ pulumi up
35 | ```
36 |
37 | 4. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
38 |
39 | ```bash
40 | $ pulumi destroy --yes
41 | $ pulumi stack rm --yes
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/wordpress/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/apps/wordpress/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-wordpress",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/kubernetes": "latest",
9 | "@pulumi/pulumi": "latest",
10 | "@pulumi/random": "latest"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/apps/wordpress/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/aws/01-identity/.gitignore:
--------------------------------------------------------------------------------
1 | /.pulumi/
2 | /.vscode/
3 | bin/
4 | node_modules/
5 | *.pyc
6 | .Python
7 | include/
8 | lib/
9 | yarn.lock
10 | yarn-error.log
11 | package-lock.json
12 | Pulumi.*.yaml
13 | .idea/
14 | *.iml
15 |
16 | infra-ci-client-secret.json
17 | k8s-app-dev-ci-client-secret.json
18 |
--------------------------------------------------------------------------------
/aws/01-identity/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-aws-identity
2 | description: Creates an identity stack for an AWS EKS cluster and its users.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/aws/01-identity/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/aws/01-identity/README.md)
2 |
3 | # Identity - AWS
4 |
5 | Create the Identity resources to deploy EKS.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/identity)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Configure the stack.
35 |
36 | ```bash
37 | $ pulumi config set aws:region us-west-2
38 | ```
39 |
40 | 1. Update the stack.
41 |
42 | ```bash
43 | $ pulumi up
44 | ```
45 |
46 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
47 |
48 | ```bash
49 | $ pulumi destroy --yes
50 | $ pulumi stack rm --yes
51 | ```
52 |
--------------------------------------------------------------------------------
/aws/01-identity/index.ts:
--------------------------------------------------------------------------------
1 | import * as aws from "@pulumi/aws";
2 | import * as pulumi from "@pulumi/pulumi";
3 |
4 | // The managed policies EKS requires of nodegroups join a cluster.
5 | const nodegroupManagedPolicyArns: string[] = [
6 | "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
7 | "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
8 | "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
9 | ];
10 |
11 | // Create the EKS cluster admins role.
12 | const adminsName = "admins";
13 | const adminsIamRole = new aws.iam.Role(`${adminsName}-eksClusterAdmin`, {
14 | assumeRolePolicy: aws.getCallerIdentity().then(id =>
15 | aws.iam.assumeRolePolicyForPrincipal({"AWS": `arn:aws:iam::${id.accountId}:root`}))
16 | })
17 | export const adminsIamRoleArn = adminsIamRole.arn;
18 | const adminsIamRolePolicy = new aws.iam.RolePolicy(`${adminsName}-eksClusterAdminPolicy`, {
19 | role: adminsIamRole,
20 | policy: {
21 | Version: "2012-10-17",
22 | Statement: [
23 | { Effect: "Allow", Action: ["eks:*", "ec2:DescribeImages"], Resource: "*", },
24 | { Effect: "Allow", Action: "iam:PassRole", Resource: "*"},
25 | ],
26 | },
27 | },
28 | { parent: adminsIamRole },
29 | );
30 |
31 | // Create the EKS cluster developers role.
32 | const devName = "devs";
33 | const devsIamRole = new aws.iam.Role(`${devName}-eksClusterDeveloper`, {
34 | assumeRolePolicy: aws.getCallerIdentity().then(id =>
35 | aws.iam.assumeRolePolicyForPrincipal({"AWS": `arn:aws:iam::${id.accountId}:root`}))
36 | })
37 | export const devsIamRoleArn = devsIamRole.arn;
38 |
39 | // Create the standard node group worker role and attach the required policies.
40 | const stdName = "standardNodeGroup";
41 | const stdNodegroupIamRole = new aws.iam.Role(`${stdName}-eksClusterWorkerNode`, {
42 | assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({"Service": "ec2.amazonaws.com"})
43 | })
44 | attachPoliciesToRole(stdName, stdNodegroupIamRole, nodegroupManagedPolicyArns);
45 | export const stdNodegroupIamRoleArn = stdNodegroupIamRole.arn;
46 |
47 | // Create the performant node group worker role and attach the required policies.
48 | const perfName = "performanceNodeGroup";
49 | const perfNodegroupIamRole = new aws.iam.Role(`${perfName}-eksClusterWorkerNode`, {
50 | assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({"Service": "ec2.amazonaws.com"})
51 | })
52 | attachPoliciesToRole(perfName, perfNodegroupIamRole, nodegroupManagedPolicyArns);
53 | export const perfNodegroupIamRoleArn = perfNodegroupIamRole.arn;
54 |
55 | // Attach policies to a role.
56 | function attachPoliciesToRole(name: string, role: aws.iam.Role, policyArns: string[]) {
57 | for (const policyArn of policyArns) {
58 | new aws.iam.RolePolicyAttachment(`${name}-${policyArn.split('/')[1]}`,
59 | { policyArn: policyArn, role: role },
60 | );
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/aws/01-identity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-aws-identity",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/aws": "latest",
9 | "@pulumi/pulumi": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/aws/01-identity/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/aws/02-managed-infra/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-aws-infra
2 | description: Creates an managed infrastructure stack for an AWS EKS cluster.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/aws/02-managed-infra/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/aws/02-managed-infra/README.md)
2 |
3 | # Managed Infrastructure - AWS
4 |
5 | Create the Managed Infrastructure resources to deploy EKS.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/managed-infra)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Configure the stack.
35 |
36 | ```bash
37 | $ pulumi config set aws:region us-west-2
38 | ```
39 |
40 | 1. Update the stack.
41 |
42 | ```bash
43 | $ pulumi up
44 | ```
45 |
46 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
47 |
48 | ```bash
49 | $ pulumi destroy --yes
50 | $ pulumi stack rm --yes
51 | ```
52 |
--------------------------------------------------------------------------------
/aws/02-managed-infra/index.ts:
--------------------------------------------------------------------------------
1 | import * as awsx from "@pulumi/awsx";
2 |
3 | // Create a new VPC with custom settings.
4 | const vpcName = "eksVpc";
5 | const vpc = new awsx.ec2.Vpc(vpcName, {
6 | cidrBlock: "172.16.0.0/16",
7 | numberOfAvailabilityZones: "all",
8 | tags: { "Name": vpcName },
9 | });
10 |
11 | // Export the VPC resource IDs.
12 | export const vpcId = vpc.id;
13 | export const publicSubnetIds = vpc.publicSubnetIds;
14 | export const privateSubnetIds = vpc.privateSubnetIds;
15 |
16 | /*
17 | // Use the default VPC
18 | const defaultVpc = awsx.ec2.Vpc.getDefault();
19 |
20 | // Export the VPC resource IDs.
21 | export const defaultVpcId = defaultVpc.id;
22 | export const defaultPublicSubnetIds = defaultVpc.publicSubnetIds;
23 | export const defaultPrivateSubnetIds = defaultVpc.privateSubnetIds;
24 | */
25 |
26 | /*
27 | // Use an existing VPC, subnets, and gateways.
28 | const existingVpc = awsx.ec2.Vpc.fromExistingIds("existingVpc", {
29 | vpcId: "vpc-00000000000000000",
30 | publicSubnetIds: ["subnet-00000000000000000", "subnet-11111111111111111"],
31 | privateSubnetIds: ["subnet-22222222222222222", "subnet-33333333333333333"],
32 | internetGatewayId: "igw-00000000000000000",
33 | natGatewayIds: ["nat-00000000000000000", "nat-11111111111111111"],
34 | })
35 |
36 | // Export the VPC resource IDs.
37 | export const existingVpcId = existingVpc.id;
38 | export const existingPublicSubnetIds = existingVpc.publicSubnetIds;
39 | export const existingPrivateSubnetIds = existingVpc.privateSubnetIds;
40 | */
41 |
--------------------------------------------------------------------------------
/aws/02-managed-infra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-aws-infra",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/awsx": "latest",
9 | "@pulumi/pulumi": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/aws/02-managed-infra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/aws/03-cluster-configuration/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-aws-cluster
2 | description: Creates an EKS cluster using best-practices.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/aws/03-cluster-configuration/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/aws/03-cluster-configuration/README.md)
2 |
3 | # Cluster Configuration - AWS
4 |
5 | Create the EKS Cluster and Kubernetes Defaults.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/control-plane)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-aws-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/aws/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-aws-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set aws:region us-west-2
55 | $ pulumi config set k8s-aws-cluster:identityStackRef myUser/k8s-aws-identity/dev-1573589109
56 | $ pulumi config set k8s-aws-cluster:infraStackRef myUser/k8s-aws-infra/dev-1573589378
57 | ```
58 |
59 | 1. Update the stack.
60 |
61 | ```bash
62 | $ pulumi up
63 | ```
64 |
65 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
66 |
67 | ```bash
68 | $ pulumi destroy --yes
69 | $ pulumi stack rm --yes
70 | ```
71 |
--------------------------------------------------------------------------------
/aws/03-cluster-configuration/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const identityStackRef = new pulumi.StackReference(pulumiConfig.require("identityStackRef"));
8 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
9 |
10 | export const config = {
11 | // Identity
12 | adminsIamRoleArn: identityStackRef.getOutput("adminsIamRoleArn"),
13 | devsIamRoleArn : identityStackRef.getOutput("devsIamRoleArn"),
14 | stdNodegroupIamRoleArn : identityStackRef.getOutput("stdNodegroupIamRoleArn"),
15 | perfNodegroupIamRoleArn: identityStackRef.getOutput("perfNodegroupIamRoleArn"),
16 |
17 | // Infrastructure / Networking
18 | vpcId: infraStackRef.getOutput("vpcId"),
19 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
20 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
21 |
22 | /*
23 | defaultVpcId: infraStackRef.getOutput("defaultVpcId"),
24 | defaultPublicSubnetIds: infraStackRef.getOutput("defaultPublicSubnetIds"),
25 | defaultPrivateSubnetIds: infraStackRef.getOutput("defaultPrivateSubnetIds"),
26 | */
27 |
28 | /*
29 | existingVpcId: infraStackRef.getOutput("existingVpcId"),
30 | existingPublicSubnetIds: infraStackRef.getOutput("existingPublicSubnetIds"),
31 | existingPrivateSubnetIds: infraStackRef.getOutput("existingPrivateSubnetIds"),
32 | */
33 | };
34 |
--------------------------------------------------------------------------------
/aws/03-cluster-configuration/iam.ts:
--------------------------------------------------------------------------------
1 | import * as aws from "@pulumi/aws";
2 |
3 | // Creates a collection of IAM instance profiles from the given roles.
4 | export function createInstanceProfiles(name: string, roles: aws.iam.Role[]): aws.iam.InstanceProfile[] {
5 | const profiles: aws.iam.InstanceProfile[] = [];
6 |
7 | for (let i = 0; i < roles.length; i++) {
8 | const role = roles[i];
9 | profiles.push(new aws.iam.InstanceProfile(`${name}-instanceProfile-${i}`, {role: role}));
10 | }
11 |
12 | return profiles;
13 | }
14 |
--------------------------------------------------------------------------------
/aws/03-cluster-configuration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-aws-cluster",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/aws": "latest",
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/pulumi": "latest",
11 | "@pulumi/eks": "latest"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/aws/03-cluster-configuration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/aws/04-cluster-services/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-aws-cluster-svcs
2 | description: Deploys common EKS cluster services.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/aws/04-cluster-services/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/aws/04-cluster-services/README.md)
2 |
3 | # Cluster Services - AWS
4 |
5 | Deploy Cluster Services in the EKS Cluster.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/cluster-services)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-aws-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/aws/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-aws-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set aws:region us-west-2
55 | $ pulumi config set k8s-aws-cluster-svcs:identityStackRef myUser/k8s-aws-identity/dev-1573589109
56 | $ pulumi config set k8s-aws-cluster-svcs:clusterStackRef myUser/k8s-aws-cluster/dev-1571780002
57 | ```
58 |
59 | 1. Update the stack.
60 |
61 | ```bash
62 | $ pulumi up
63 | ```
64 |
65 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
66 |
67 | ```bash
68 | $ pulumi destroy --yes
69 | $ pulumi stack rm --yes
70 | ```
71 |
--------------------------------------------------------------------------------
/aws/04-cluster-services/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const identityStackRef = new pulumi.StackReference(pulumiConfig.require("identityStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Identity
12 | stdNodegroupIamRoleArn : identityStackRef.getOutput("stdNodegroupIamRoleArn"),
13 | perfNodegroupIamRoleArn: identityStackRef.getOutput("perfNodegroupIamRoleArn"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
19 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
20 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
21 | };
22 |
--------------------------------------------------------------------------------
/aws/04-cluster-services/index.ts:
--------------------------------------------------------------------------------
1 | import * as aws from "@pulumi/aws";
2 | import * as k8s from "@pulumi/kubernetes";
3 | import * as pulumi from "@pulumi/pulumi";
4 | import { config } from "./config";
5 |
6 | const projectName = pulumi.getProject();
7 |
8 | export const stdNodegroupIamRoleArn = config.stdNodegroupIamRoleArn
9 | export const perfNodegroupIamRoleArn = config.perfNodegroupIamRoleArn
10 | const stdNodegroupIamRoleName = stdNodegroupIamRoleArn.apply(s => s.split("/")).apply(s => s[1])
11 | const perfNodegroupIamRoleName = perfNodegroupIamRoleArn.apply(s => s.split("/")).apply(s => s[1])
12 | export const clusterName = config.clusterName
13 |
14 | // Create a new IAM Policy for fluentd-cloudwatch to manage CloudWatch Logs.
15 | const name = "fluentd-cloudwatch";
16 | const fluentdCloudWatchPolicy = new aws.iam.Policy(name,
17 | {
18 | description: "Allows fluentd-cloudwatch to work with CloudWatch Logs.",
19 | policy: JSON.stringify(
20 | {
21 | Version: "2012-10-17",
22 | Statement: [{Effect: "Allow", Action: ["logs:*"], Resource: ["arn:aws:logs:*:*:*"]}]
23 | }
24 | )
25 | },
26 | );
27 |
28 | // Attach CloudWatch Logs policies to a role.
29 | function attachLogPolicies(name: string, arn: pulumi.Input) {
30 | new aws.iam.RolePolicyAttachment(name,
31 | { policyArn: fluentdCloudWatchPolicy.arn, role: arn},
32 | );
33 | }
34 |
35 | attachLogPolicies("stdRpa", stdNodegroupIamRoleName);
36 | attachLogPolicies("perfRpa", perfNodegroupIamRoleName);
37 |
38 | // Deploy fluentd using the Helm chart.
39 | const provider = new k8s.Provider("provider", {kubeconfig: config.kubeconfig});
40 | const fluentdCloudWatchLogGroup = new aws.cloudwatch.LogGroup(name);
41 | export let fluentdCloudWatchLogGroupName = fluentdCloudWatchLogGroup.name;
42 | const fluentdCloudwatch = new k8s.helm.v2.Chart(name,
43 | {
44 | namespace: config.clusterSvcsNamespaceName,
45 | chart: "fluentd-cloudwatch",
46 | version: "0.11.0",
47 | fetchOpts: {
48 | repo: "https://kubernetes-charts-incubator.storage.googleapis.com/",
49 | },
50 | values: {
51 | extraVars: [ "{ name: FLUENT_UID, value: '0' }" ],
52 | rbac: {create: true},
53 | awsRegion: aws.config.region,
54 | logGroupName: fluentdCloudWatchLogGroup.name,
55 | },
56 | transformations: [
57 | (obj: any) => {
58 | // Do transformations on the YAML to set the namespace
59 | if (obj.metadata) {
60 | obj.metadata.namespace = config.clusterSvcsNamespaceName;
61 | }
62 | },
63 | ],
64 | },
65 | {providers: { kubernetes: provider }},
66 | );
67 |
--------------------------------------------------------------------------------
/aws/04-cluster-services/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-aws-cluster-svcs",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/aws": "latest",
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/pulumi": "latest"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/aws/04-cluster-services/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/aws/05-app-services/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-aws-apps-svcs
2 | description: Deploys common EKS app services.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/aws/05-app-services/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/aws/05-app-services/README.md)
2 |
3 | # App Services - AWS
4 |
5 | Deploy App Services in the EKS Cluster.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/app-services)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-aws-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/aws/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-aws-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set aws:region us-west-2
55 | $ pulumi config set k8s-aws-apps-svcs:infraStackRef myUser/k8s-aws-infra/dev-1573589378 && \
56 | $ pulumi config set k8s-aws-apps-svcs:clusterStackRef myUser/k8s-aws-cluster/dev-1571780002
57 | ```
58 |
59 | 1. Update the stack.
60 |
61 | ```bash
62 | $ pulumi up
63 | ```
64 |
65 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
66 |
67 | ```bash
68 | $ pulumi destroy --yes
69 | $ pulumi stack rm --yes
70 | ```
71 |
--------------------------------------------------------------------------------
/aws/05-app-services/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/aws/05-app-services/index.ts:
--------------------------------------------------------------------------------
1 | import * as aws from "@pulumi/aws";
2 | import * as k8s from "@pulumi/kubernetes";
3 | import * as pulumi from "@pulumi/pulumi";
4 | import * as random from "@pulumi/random";
5 | import { config } from "./config";
6 |
7 | const projectName = pulumi.getProject();
8 |
9 | const privateSubnetIds = config.privateSubnetIds;
10 | const securityGroupIds = config.securityGroupIds;
11 | const clusterName = config.clusterName;
12 |
13 | // Generate a strong password for the Postgres DB.
14 | const password = new random.RandomPassword(`${projectName}-password`, {
15 | length: 16,
16 | overrideSpecial: "_%@",
17 | special: true,
18 | }).result;
19 |
20 | // Create a Postgres DB instance of RDS.
21 | const dbSubnets = new aws.rds.SubnetGroup(`${projectName}-subnets`, {
22 | subnetIds: privateSubnetIds
23 | });
24 | const db = new aws.rds.Instance("postgresdb", {
25 | engine: "postgres",
26 | instanceClass: "db.t2.micro",
27 | allocatedStorage: 20,
28 | dbSubnetGroupName: dbSubnets.id,
29 | vpcSecurityGroupIds: securityGroupIds,
30 | name: "testdb",
31 | username: "alice",
32 | password: password,
33 | skipFinalSnapshot: true,
34 | });
35 |
36 | // Create a Secret from the DB connection information.
37 | const provider = new k8s.Provider("provider", {kubeconfig: config.kubeconfig});
38 | const dbConn = new k8s.core.v1.Secret("postgres-db-conn",
39 | {
40 | data: {
41 | host: db.address.apply(addr => Buffer.from(addr).toString("base64")),
42 | port: db.port.apply(port => Buffer.of(port).toString("base64")),
43 | username: db.username.apply(user => Buffer.from(user).toString("base64")),
44 | password: password.apply(pass => Buffer.from(pass).toString("base64")),
45 | },
46 | },
47 | {provider: provider},
48 | );
49 |
50 | // Create a Redis instance.
51 | const cacheSubnets = new aws.elasticache.SubnetGroup(`${projectName}-cache-subnets`, {
52 | subnetIds: privateSubnetIds,
53 | });
54 | const cacheCluster = new aws.elasticache.Cluster("cachecluster", {
55 | engine: "redis",
56 | nodeType: "cache.t2.micro",
57 | numCacheNodes: 1,
58 | subnetGroupName: cacheSubnets.id,
59 | securityGroupIds: securityGroupIds,
60 | });
61 |
62 | // Create a ConfigMap from the cache connection information.
63 | const cacheConn = new k8s.core.v1.ConfigMap("postgres-db-conn",
64 | {
65 | data: {
66 | host: cacheCluster.cacheNodes[0].address.apply(addr => Buffer.from(addr).toString("base64")),
67 | },
68 | },
69 | {provider: provider},
70 | );
71 |
--------------------------------------------------------------------------------
/aws/05-app-services/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-aws-apps-svcs",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/aws": "latest",
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/random": "latest",
11 | "@pulumi/pulumi": "latest"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/aws/05-app-services/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-deploy-container
2 | description: Build and push image to private registry and create a Deployment from it.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/aws/06-apps/build-deploy-container/README.md)
2 |
3 | # Build container image and push to private registry on AWS
4 |
5 | This example builds a container image of a simple Node app and pushes the image
6 | to a private registry on ECR. The image is used to create a Kubernetes
7 | Deployment.
8 |
9 | ## Deploying the App
10 |
11 | To deploy your infrastructure, follow the below steps.
12 |
13 | ### Prerequisites
14 |
15 | 1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/)
16 | 1. [Install Node.js 8.11.3](https://nodejs.org/en/download/)
17 | 1. [Install Docker](https://docs.docker.com/v17.09/engine/installation/)
18 | 1. [Configure AWS Credentials](https://www.pulumi.com/docs/intro/cloud-providers/aws/setup/)
19 | 1. [Configure access to a Kubernetes cluster](https://kubernetes.io/docs/setup/)
20 |
21 | ### Steps
22 |
23 | After cloning this repo, from this working directory, run these commands:
24 |
25 | 1. Install the required Node.js packages:
26 |
27 | ```bash
28 | $ npm install
29 | ```
30 |
31 | 2. Create a new stack, which is an isolated deployment target for this example:
32 |
33 | ```bash
34 | $ pulumi stack init
35 | ```
36 |
37 | 3. Set the required configuration variables for this program:
38 |
39 | ```bash
40 | $ pulumi config set aws:region us-west-2 # Any valid AWS region here.
41 | ```
42 |
43 | Note that you can choose different regions here.
44 |
45 | 4. Bring up the stack, which will create the cloud resources, build and push the image to the private registry,
46 | and then create a Deployment using that image.
47 |
48 | ```bash
49 | $ pulumi up
50 | ```
51 |
52 | 5. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
53 |
54 | ```bash
55 | $ pulumi destroy --yes
56 | $ pulumi stack rm --yes
57 | ```
58 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as awsx from "@pulumi/awsx";
16 | import * as k8s from "@pulumi/kubernetes";
17 | import * as kx from "@pulumi/kubernetesx";
18 | import { config } from "./config";
19 |
20 | // Create a new VPC with custom settings.
21 | const vpcName = "eksVpc";
22 | const vpc = new awsx.ec2.Vpc(vpcName, {
23 | cidrBlock: "172.16.0.0/16",
24 | tags: { "Name": vpcName },
25 | });
26 |
27 | // Export the VPC resource IDs.
28 | export const vpcId = vpc.vpcId;
29 | export const publicSubnetIds = vpc.publicSubnetIds;
30 | export const privateSubnetIds = vpc.privateSubnetIds;
31 |
32 | // Create a repository.
33 | const repo = new awsx.ecr.Repository("repo", {
34 | forceDelete: true,
35 | });
36 |
37 | // Build a Docker image from a local Dockerfile context in the
38 | // './node-app' directory, and push it to the registry.
39 | const customImage = "node-app";
40 | const appImage = new awsx.ecr.Image("image", {
41 | repositoryUrl: repo.url,
42 | path: `./${customImage}`,
43 | });
44 |
45 | // Create a k8s provider.
46 | const provider = new k8s.Provider("provider", {
47 | kubeconfig: config.kubeconfig,
48 | namespace: config.appsNamespaceName,
49 | });
50 |
51 | // Create a Deployment of the built container.
52 | const appLabels = { app: customImage };
53 | const appDeployment = new k8s.apps.v1.Deployment("app", {
54 | spec: {
55 | selector: { matchLabels: appLabels },
56 | replicas: 1,
57 | template: {
58 | metadata: { labels: appLabels },
59 | spec: {
60 | containers: [{
61 | name: customImage,
62 | image: appImage.imageUri,
63 | ports: [{name: "http", containerPort: 80}],
64 | }],
65 | }
66 | },
67 | }
68 | }, { provider: provider });
69 |
70 | //
71 | // Example using kx.
72 | //
73 |
74 | // Define the Pod for the Deployment.
75 | const pb = new kx.PodBuilder({
76 | containers: [{
77 | image: appImage.imageUri,
78 | ports: { "http": 80 },
79 | }],
80 | });
81 |
82 | // Create a Deployment of the Pod defined by the PodBuilder.
83 | const appDeploymentKx = new kx.Deployment("app-kx", {
84 | spec: pb.asDeploymentSpec(),
85 | }, { provider: provider });
86 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/node-app/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/node-app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:8.9.3-alpine
2 | RUN mkdir -p /usr/src/app
3 | COPY ./app/* /usr/src/app/
4 | WORKDIR /usr/src/app
5 | RUN npm install
6 | CMD node /usr/src/app/index.js
7 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/node-app/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello, world!
4 |
5 |
6 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/node-app/app/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const morgan = require('morgan');
3 |
4 | const app = express();
5 | app.use(morgan('combined'));
6 |
7 | app.get('/', (req, res) => {
8 | res.sendFile(__dirname + '/index.html')
9 | });
10 |
11 | var listener = app.listen(process.env.PORT || 80, function() {
12 | console.log('listening on port ' + listener.address().port);
13 | });
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/node-app/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-helloworld",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "dependencies": {
7 | "express": "^4.14.0",
8 | "morgan": "^1.8.2"
9 | },
10 | "devDependencies": {},
11 | "author": ""
12 | }
13 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-aws-apps-deploy-container",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/awsx": "latest",
9 | "@pulumi/docker": "latest",
10 | "@pulumi/kubernetes": "latest",
11 | "@pulumi/kubernetesx": "^0.1.0",
12 | "@pulumi/pulumi": "latest"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/aws/06-apps/build-deploy-container/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/azure/01-identity/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-az-identity
2 | description: Creates an identity stack for an AKS cluster and its users.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/azure/01-identity/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/azure/01-identity/README.md)
2 |
3 | # Identity - Azure
4 |
5 | Create the Identity resources to deploy AKS.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/identity)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Configure the stack.
35 |
36 | ```bash
37 | $ pulumi config set azure:location westus2
38 | ```
39 |
40 | 1. Update the stack.
41 |
42 | ```bash
43 | $ pulumi up
44 | ```
45 |
46 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
47 |
48 | ```bash
49 | $ pulumi destroy --yes
50 | $ pulumi stack rm --yes
51 | ```
52 |
--------------------------------------------------------------------------------
/azure/01-identity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-az-identity",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/azure": "latest",
9 | "@pulumi/azuread": "latest",
10 | "@pulumi/random": "latest",
11 | "@pulumi/pulumi": "latest"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/azure/01-identity/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/azure/02-managed-infra/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-az-infra
2 | description: Creates a managed infrastructure stack for an AKS cluster.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/azure/02-managed-infra/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/azure/02-managed-infra/README.md)
2 |
3 | # Managed Infrastructure - Azure
4 |
5 | Create the Managed Infrastructure resources to deploy AKS.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/managed-infra)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-az-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/azure/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-az-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set azure:location westus2
55 | $ pulumi config set k8s-az-infra:identityStackRef myUser/k8s-az-identity/dev-1573591216
56 | ```
57 |
58 | 1. Update the stack.
59 |
60 | ```bash
61 | $ pulumi up
62 | ```
63 |
64 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
65 |
66 | ```bash
67 | $ pulumi destroy --yes
68 | $ pulumi stack rm --yes
69 | ```
70 |
--------------------------------------------------------------------------------
/azure/02-managed-infra/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | const pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const identityStackRef = new pulumi.StackReference(pulumiConfig.require("identityStackRef"));
8 |
9 | export const config = {
10 | // Resource Group
11 | resourceGroupName: identityStackRef.getOutput("resourceGroupName"),
12 | };
13 |
--------------------------------------------------------------------------------
/azure/02-managed-infra/index.ts:
--------------------------------------------------------------------------------
1 | import * as azure from "@pulumi/azure";
2 | import * as pulumi from "@pulumi/pulumi";
3 | import { config } from "./config";
4 |
5 | const name = pulumi.getProject();
6 |
7 | // Create a Virtual Network for the cluster
8 | const vnet = new azure.network.VirtualNetwork(name, {
9 | resourceGroupName: config.resourceGroupName,
10 | addressSpaces: ["10.2.0.0/16"],
11 | });
12 |
13 | // Create a Subnet for the cluster
14 | const subnet = new azure.network.Subnet(name, {
15 | resourceGroupName: config.resourceGroupName,
16 | virtualNetworkName: vnet.name,
17 | addressPrefix: "10.2.1.0/24",
18 | });
19 |
20 | // Log and Monitoring workspace
21 | const loganalytics = new azure.operationalinsights.AnalyticsWorkspace(name, {
22 | resourceGroupName: config.resourceGroupName,
23 | sku: "PerGB2018",
24 | retentionInDays: 30,
25 | });
26 |
27 | // Export outputs for other stacks
28 | export const subnetId = subnet.id;
29 | export const logAnalyticsWorkspaceId = loganalytics.id;
30 |
--------------------------------------------------------------------------------
/azure/02-managed-infra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-az-infra",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/azure": "latest",
9 | "@pulumi/pulumi": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/azure/02-managed-infra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "config.ts",
23 | "index.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/azure/03-cluster-configuration/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-az-cluster
2 | description: Creates an Azure cluster using best-practices.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/azure/03-cluster-configuration/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/azure/03-cluster-configuration/README.md)
2 |
3 | # Cluster Configuration - Azure
4 |
5 | Create the AKS Cluster and Kubernetes Defaults.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/control-plane)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-az-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/azure/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-az-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set azure:location westus2
55 | $ pulumi config set k8s-az-cluster:identityStackRef metral/k8s-az-identity/dev-1573591216
56 | $ pulumi config set k8s-az-cluster:infraStackRef metral/k8s-az-infra/dev-1573591518
57 | ```
58 |
59 | 1. Update the stack.
60 |
61 | ```bash
62 | $ pulumi up
63 | ```
64 |
65 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
66 |
67 | ```bash
68 | $ pulumi destroy --yes
69 | $ pulumi stack rm --yes
70 | ```
71 |
--------------------------------------------------------------------------------
/azure/03-cluster-configuration/config.ts:
--------------------------------------------------------------------------------
1 | import * as azure from "@pulumi/azure";
2 | import * as pulumi from "@pulumi/pulumi";
3 |
4 | const pulumiConfig = new pulumi.Config();
5 |
6 | // Existing Pulumi stack reference in the format:
7 | // // e.g. "myUser/myProject/dev"
8 |
9 | const identityStackRef = new pulumi.StackReference(pulumiConfig.require("identityStackRef"));
10 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
11 |
12 | export const config = {
13 | // Resource Group
14 | resourceGroupName: identityStackRef.getOutput("resourceGroupName"),
15 |
16 | // Identity
17 | adServerAppId: identityStackRef.getOutput("adServerAppId"),
18 | adServerAppSecret: identityStackRef.getOutput("adServerAppSecret"),
19 | adClientAppId: identityStackRef.getOutput("adClientAppId"),
20 | adClientAppSecret: identityStackRef.getOutput("adClientAppSecret"),
21 | adGroupAdmins: identityStackRef.getOutput("adGroupAdmins"),
22 | adGroupDevs: identityStackRef.getOutput("adGroupDevs"),
23 |
24 | // Infrastructure / Networking
25 | subnetId: infraStackRef.getOutput("subnetId"),
26 | logAnalyticsWorkspaceId: infraStackRef.getOutput("logAnalyticsWorkspaceId"),
27 | };
28 |
--------------------------------------------------------------------------------
/azure/03-cluster-configuration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-az-cluster",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/azure": "latest",
9 | "@pulumi/tls": "latest",
10 | "@pulumi/kubernetes": "latest",
11 | "@pulumi/pulumi": "latest"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/azure/03-cluster-configuration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "config.ts",
23 | "index.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/azure/04-cluster-services/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-az-cl-svcs
2 | description: Creates Azure Cluster Services for an AKS cluster.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/azure/04-cluster-services/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/azure/04-cluster-services/README.md)
2 |
3 | # Cluster Services - Azure
4 |
5 | Deploy Cluster Services in the AKS cluster.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/cluster-services)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-az-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/azure/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-az-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set azure:location westus2
55 | $ pulumi config set k8s-az-cl-svcs:infraStackRef myUser/k8s-az-infra/dev-1573591518
56 | $ pulumi config set k8s-az-cl-svcs:clusterStackRef myUser/k8s-az-cluster/dev-1573591790
57 | ```
58 |
59 | 1. Update the stack.
60 |
61 | ```bash
62 | $ pulumi up
63 | ```
64 |
65 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
66 |
67 | ```bash
68 | $ pulumi destroy --yes
69 | $ pulumi stack rm --yes
70 | ```
71 |
--------------------------------------------------------------------------------
/azure/04-cluster-services/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | const pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infrastructure
12 | logAnalyticsWorkspaceId: infraStackRef.getOutput("logAnalyticsWorkspaceId"),
13 |
14 | // AKS Cluster
15 | clusterId: clusterStackRef.getOutput("clusterId"),
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | };
18 |
--------------------------------------------------------------------------------
/azure/04-cluster-services/index.ts:
--------------------------------------------------------------------------------
1 | import * as azure from "@pulumi/azure";
2 | import * as pulumi from "@pulumi/pulumi";
3 | import { config } from "./config";
4 |
5 | const name = pulumi.getProject();
6 |
7 | // Enable the Monitoring Diagonostic control plane component logs and AllMetrics
8 | const azMonitoringDiagnostic = new azure.monitoring.DiagnosticSetting(name, {
9 | logAnalyticsWorkspaceId: config.logAnalyticsWorkspaceId,
10 | targetResourceId: config.clusterId,
11 | logs: ["kube-apiserver", "kube-controller-manager", "kube-scheduler", "kube-audit", "cluster-autoscaler"]
12 | .map(category => ({
13 | category,
14 | enabled : true,
15 | retentionPolicy: { enabled: true },
16 | })),
17 | metrics: [{
18 | category: "AllMetrics",
19 | retentionPolicy: { enabled: true },
20 | }],
21 | });
22 |
--------------------------------------------------------------------------------
/azure/04-cluster-services/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-az-cl-svcs",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/azure": "latest",
9 | "@pulumi/pulumi": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/azure/04-cluster-services/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "config.ts",
23 | "index.ts"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/azure/05-app-services/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-az-apps-svcs
2 | description: Creates Application Services for an AKS cluster.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/azure/05-app-services/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/azure/05-app-services/README.md)
2 |
3 | # App Services - Azure
4 |
5 | Deploy App Services in the AKS cluster.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/app-services)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-az-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/azure/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-az-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set azure:location westus2
55 | $ pulumi config set k8s-az-apps-svcs:identityStackRef myUser/k8s-az-infra/dev-1573591518 && \
56 | $ pulumi config set k8s-az-cl-svcs:infraStackRef myUser/k8s-az-infra/dev-1573591518
57 | $ pulumi config set k8s-az-cl-svcs:clusterStackRef myUser/k8s-az-cluster/dev-1573591790
58 | ```
59 |
60 | 1. Update the stack.
61 |
62 | ```bash
63 | $ pulumi up
64 | ```
65 |
66 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
67 |
68 | ```bash
69 | $ pulumi destroy --yes
70 | $ pulumi stack rm --yes
71 | ```
72 |
--------------------------------------------------------------------------------
/azure/05-app-services/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as pulumi from "@pulumi/pulumi";
4 |
5 | const pulumiConfig = new pulumi.Config();
6 |
7 | // Existing Pulumi stack reference in the format:
8 | // // e.g. "myUser/myProject/dev"
9 |
10 | const identityStackRef = new pulumi.StackReference(pulumiConfig.require("identityStackRef"));
11 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
12 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
13 |
14 | export const config = {
15 | // Resource Group
16 | resourceGroupName: identityStackRef.getOutput("resourceGroupName"),
17 |
18 | // Identity
19 | adApplicationId: identityStackRef.getOutput("adApplicationId"),
20 | adSpPassword: identityStackRef.getOutput("adSpPassword"),
21 |
22 | // Infrastructure / Networking
23 | subnetId: infraStackRef.getOutput("subnetId"),
24 | logAnalyticsWorkspaceId: infraStackRef.getOutput("logAnalyticsWorkspaceId"),
25 |
26 | // AKS Cluster
27 | clusterId: clusterStackRef.getOutput("clusterId"),
28 | kubeconfig: clusterStackRef.getOutput("kubeconfigAdmin"),
29 | clusterName: clusterStackRef.getOutput("clusterName"),
30 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
31 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
32 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
33 | };
34 |
--------------------------------------------------------------------------------
/azure/05-app-services/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as azure from "@pulumi/azure";
4 | import * as k8s from "@pulumi/kubernetes";
5 | import * as pulumi from "@pulumi/pulumi";
6 |
7 | import { config } from "./config";
8 | import * as mongoHelpers from "./mongoHelpers";
9 |
10 | const name = pulumi.getProject();
11 |
12 | // Define a separate resource group for app services.
13 | const resourceGroup = new azure.core.ResourceGroup(name);
14 |
15 | // Create a MongoDB-flavored instance of CosmosDB.
16 | const cosmosdb = new azure.cosmosdb.Account("k8s-az-mongodb", {
17 | resourceGroupName: resourceGroup.name,
18 | kind: "MongoDB",
19 | consistencyPolicy: {
20 | consistencyLevel: "Session",
21 | },
22 | offerType: "Standard",
23 | geoLocations: [
24 | { location: resourceGroup.location, failoverPriority: 0 },
25 | ],
26 | });
27 |
28 | // A k8s provider instance of the cluster.
29 | const provider = new k8s.Provider(`${name}-aks`, {
30 | kubeconfig: config.kubeconfig,
31 | });
32 |
33 | // Create secret from MongoDB connection string.
34 | const mongoConnStrings = new k8s.core.v1.Secret(
35 | "mongo-secrets",
36 | {
37 | metadata: { name: "mongo-secrets", namespace: config.appsNamespaceName},
38 | data: mongoHelpers.parseConnString(cosmosdb.connectionStrings),
39 | },
40 | { provider },
41 | );
42 |
--------------------------------------------------------------------------------
/azure/05-app-services/mongoHelpers.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation. All rights reserved.
2 |
3 | import * as pulumi from "@pulumi/pulumi";
4 |
5 | export function parseConnString(
6 | conns: pulumi.Output,
7 | ): pulumi.Output<{ [key: string]: string }> {
8 | // Per the official docs[1], the format of this connection string is:
9 | //
10 | // mongodb://username:password@host:port/[database]?ssl=true
11 | //
12 | // Where these could have the following values:
13 | //
14 | // {
15 | // username: "cosmosdb93a4133a",
16 | // password: "23maXrWsrzZ1LmPe4w6XNGRJJTHsqGZPDTjyVQNbPaw119KCoCNpStH0DQms5MKdyAecisBM9uWbpV7lUnyNeQ==",
17 | // host: "cosmosdb93a4133a.documents.azure.com",
18 | // port: "10255",
19 | // database: "mydatabase"
20 | // }
21 | //
22 | // There are a few subtleties involved in getting the Bitnami node Chart to actually be able to
23 | // use this:
24 | //
25 | // 1. The `database` field is optional, we default to `test`, as the API expects.
26 | // 2. The node Chart expects the components of this connection string to be parsed and
27 | // presented in files in a `Secret`. The CosmosDb API doesn't natively expose this, so we
28 | // must parse it ourselves.
29 | // 3. The node Chart uses mongoose to speak the MongoDB wire protocol to CosmosDB. Mongoose
30 | // fails to parse base64-encoded passwords because it doesn't like the `=` character. This
31 | // means we have to (1) URI-encode the password component ourselves, and (2) base64-encode
32 | // that URI-encoded password, because this is the format Kubernetes expects.
33 | //
34 | // [1]: https://docs.microsoft.com/en-us/azure/cosmos-db/connect-mongodb-account
35 |
36 | function toBase64(s: string): string {
37 | return Buffer.from(s).toString("base64");
38 | }
39 |
40 | return conns.apply(conns => {
41 | const conn = conns[0];
42 | const noProtocol = conn.replace(/^mongodb\:\/\//, "");
43 | const [username, rest1, rest2] = noProtocol.split(":", 3);
44 | const [password, host] = rest1.split("@", 2);
45 | const [port, rest3] = rest2.split("/", 2);
46 | const database = rest3.replace(/\?ssl=true$/, "");
47 | return {
48 | host: toBase64(host),
49 | port: toBase64(port),
50 | username: toBase64(username),
51 | password: toBase64(encodeURIComponent(password)),
52 | database: toBase64(database === "" ? "test" : database),
53 | };
54 | });
55 | }
56 |
--------------------------------------------------------------------------------
/azure/05-app-services/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-az-app-svcs",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/azure": "latest",
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/pulumi": "latest"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/azure/05-app-services/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "config.ts",
23 | "index.ts",
24 | "mongoHelpers.ts"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-deploy-container
2 | description: Build and push image to private registry and create a Deployment from it.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/azure/06-apps/build-deploy-container/README.md)
2 |
3 | # Build container image and push to private registry on Azure
4 |
5 | This example builds a container image of a simple Node app and pushes the image
6 | to a private registry on Azure. The image is used to create a Kubernetes
7 | Deployment.
8 |
9 | ## Deploying the App
10 |
11 | To deploy your infrastructure, follow the below steps.
12 |
13 | ### Prerequisites
14 |
15 | 1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/)
16 | 1. [Install Node.js 8.11.3](https://nodejs.org/en/download/)
17 | 1. [Install Docker](https://docs.docker.com/v17.09/engine/installation/)
18 | 1. [Configure Azure Credentials](https://www.pulumi.com/docs/intro/cloud-providers/azure/setup/)
19 | 1. [Configure access to a Kubernetes cluster](https://kubernetes.io/docs/setup/)
20 |
21 | ### Steps
22 |
23 | After cloning this repo, from this working directory, run these commands:
24 |
25 | 1. Install the required Node.js packages:
26 |
27 | ```bash
28 | $ npm install
29 | ```
30 |
31 | 2. Create a new stack, which is an isolated deployment target for this example:
32 |
33 | ```bash
34 | $ pulumi stack init
35 | ```
36 |
37 | 3. Set the required configuration variables for this program:
38 |
39 | ```bash
40 | $ pulumi config set azure:location westus2 # Any valid Azure location here.
41 | ```
42 |
43 | Note that you can choose different regions here.
44 |
45 | 4. Bring up the stack, which will create the cloud resources, build and push the image to the private registry,
46 | and then create a Deployment using that image.
47 |
48 | ```bash
49 | $ pulumi up
50 | ```
51 |
52 | 5. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
53 |
54 | ```bash
55 | $ pulumi destroy --yes
56 | $ pulumi stack rm --yes
57 | ```
58 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as azure from "@pulumi/azure";
16 | import * as docker from "@pulumi/docker";
17 | import * as k8s from "@pulumi/kubernetes";
18 | import * as kx from "@pulumi/kubernetesx";
19 | import * as pulumi from "@pulumi/pulumi";
20 | import { config } from "./config";
21 |
22 | // Create an Azure Resource Group
23 | const resourceGroup = new azure.core.ResourceGroup("samples");
24 |
25 | // Create a registry in ACR.
26 | const registry = new azure.containerservice.Registry("myregistry", {
27 | resourceGroupName: resourceGroup.name,
28 | sku: "Basic",
29 | adminEnabled: true,
30 | });
31 |
32 | // Build a Docker image from a local Dockerfile context in the
33 | // './node-app' directory, and push it to the registry.
34 | const customImage = "node-app";
35 | const appImage = new docker.Image(customImage, {
36 | imageName: pulumi.interpolate`${registry.loginServer}/${customImage}:v1.0.0`,
37 | build: {
38 | context: `./${customImage}`,
39 | },
40 | registry: {
41 | server: registry.loginServer,
42 | username: registry.adminUsername,
43 | password: registry.adminPassword,
44 | },
45 | });
46 |
47 | // Create a k8s provider.
48 | const provider = new k8s.Provider("provider", {
49 | kubeconfig: config.kubeconfig,
50 | namespace: config.appsNamespaceName,
51 | });
52 |
53 | // Create a Deployment of the built container.
54 | const appLabels = { app: customImage };
55 | const appDeployment = new k8s.apps.v1.Deployment("app", {
56 | spec: {
57 | selector: { matchLabels: appLabels },
58 | replicas: 1,
59 | template: {
60 | metadata: { labels: appLabels },
61 | spec: {
62 | containers: [{
63 | name: customImage,
64 | image: appImage.imageName,
65 | ports: [{name: "http", containerPort: 80}],
66 | }],
67 | }
68 | },
69 | }
70 | }, { provider: provider });
71 |
72 | //
73 | // Example using kx.
74 | //
75 |
76 | // Define the Pod for the Deployment.
77 | const pb = new kx.PodBuilder({
78 | containers: [{
79 | image: appImage.imageName,
80 | ports: { "http": 80 },
81 | }],
82 | });
83 |
84 | // Create a Deployment of the Pod defined by the PodBuilder.
85 | const appDeploymentKx = new kx.Deployment("app-kx", {
86 | spec: pb.asDeploymentSpec(),
87 | }, { provider: provider });
88 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/node-app/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/node-app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:8.9.3-alpine
2 | RUN mkdir -p /usr/src/app
3 | COPY ./app/* /usr/src/app/
4 | WORKDIR /usr/src/app
5 | RUN npm install
6 | CMD node /usr/src/app/index.js
7 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/node-app/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello, world!
4 |
5 |
6 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/node-app/app/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const morgan = require('morgan');
3 |
4 | const app = express();
5 | app.use(morgan('combined'));
6 |
7 | app.get('/', (req, res) => {
8 | res.sendFile(__dirname + '/index.html')
9 | });
10 |
11 | var listener = app.listen(process.env.PORT || 80, function() {
12 | console.log('listening on port ' + listener.address().port);
13 | });
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/node-app/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-helloworld",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "dependencies": {
7 | "express": "^4.14.0",
8 | "morgan": "^1.8.2"
9 | },
10 | "devDependencies": {},
11 | "author": ""
12 | }
13 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-azure-apps-deploy-container",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/azure": "latest",
9 | "@pulumi/docker": "latest",
10 | "@pulumi/kubernetes": "latest",
11 | "@pulumi/kubernetesx": "^0.1.0",
12 | "@pulumi/pulumi": "latest"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/azure/06-apps/build-deploy-container/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/gcp/01-identity/.gitignore:
--------------------------------------------------------------------------------
1 | /.pulumi/
2 | /.vscode/
3 | bin/
4 | node_modules/
5 | *.pyc
6 | .Python
7 | include/
8 | lib/
9 | yarn.lock
10 | yarn-error.log
11 | package-lock.json
12 | Pulumi.*.yaml
13 | .idea/
14 | *.iml
15 |
16 | infra-ci-client-secret.json
17 | k8s-app-dev-ci-client-secret.json
18 |
--------------------------------------------------------------------------------
/gcp/01-identity/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-gcp-identity
2 | description: Creates an identity stack for an GKE cluster and its users.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/gcp/01-identity/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/gcp/01-identity/README.md)
2 |
3 | # Identity - GCP
4 |
5 | Create the Identity resources to deploy GKE.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/identity)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Configure the stack.
35 |
36 | ```bash
37 | $ pulumi config set gcp:zone us-west1-a
38 | $ pulumi config set gcp:project
39 | ```
40 |
41 | 1. Update the stack.
42 |
43 | ```bash
44 | $ pulumi up
45 | ```
46 |
47 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
48 |
49 | ```bash
50 | $ pulumi destroy --yes
51 | $ pulumi stack rm --yes
52 | ```
53 |
--------------------------------------------------------------------------------
/gcp/01-identity/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import { Config } from "@pulumi/pulumi";
16 |
17 | //
18 | // GCP-specific config.
19 | //
20 |
21 | // project is the GCP project you are going to deploy to.
22 | export const project = new Config("gcp").require("project");
23 |
--------------------------------------------------------------------------------
/gcp/01-identity/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as gcp from "@pulumi/gcp";
16 | import * as config from "./config";
17 | import * as util from "./util";
18 |
19 | // Create the GKE cluster admins ServiceAccount.
20 | const adminsName = "admins";
21 | export const adminsAccountId = `k8s-${adminsName}`;
22 | const adminsIamServiceAccount = new gcp.serviceAccount.Account(adminsName, {
23 | project: config.project,
24 | accountId: adminsAccountId,
25 | displayName: "Kubernetes Admins",
26 | });
27 |
28 | // Bind the admin ServiceAccount to be a GKE cluster admin.
29 | util.bindToRole(`${adminsName}-k8s`, adminsIamServiceAccount, {
30 | project: config.project,
31 | roles: ["roles/container.admin", "roles/container.clusterAdmin", "roles/container.developer"],
32 | });
33 |
34 | // Bind the admin ServiceAccount to be a CloudSQL admin.
35 | util.bindToRole(`${adminsName}-cloudsql`, adminsIamServiceAccount, {
36 | project: config.project,
37 | roles: ["roles/cloudsql.admin"],
38 | });
39 |
40 | // Export the admins ServiceAccount key.
41 | const adminsIamServiceAccountKey = util.createServiceAccountKey(`${adminsName}Key`, adminsIamServiceAccount);
42 |
43 | // Export the admins ServiceAccount client secret to authenticate as this service account.
44 | export const adminsIamServiceAccountSecret = util.clientSecret(adminsIamServiceAccountKey);
45 |
46 | // Create the GKE cluster developers ServiceAccount.
47 | const devsName = "devs";
48 | export const devsAccountId = `k8s-${devsName}`;
49 | const devsIamServiceAccount = new gcp.serviceAccount.Account(devsName, {
50 | project: config.project,
51 | accountId: devsAccountId,
52 | displayName: "Kubernetes Developers",
53 | });
54 |
55 |
56 | // Bind the devs ServiceAccount to be a GKE cluster developer.
57 | util.bindToRole(`${devsName}-k8s`, devsIamServiceAccount, {
58 | project: config.project,
59 | roles: ["roles/container.developer"],
60 | });
61 |
62 | // Export the devs ServiceAccount key.
63 | const devsIamServiceAccountKey = util.createServiceAccountKey(`${devsName}Key`, devsIamServiceAccount);
64 |
65 | // Export the devs ServiceAccount client secret to authenticate as this service account.
66 | export const devsIamServiceAccountSecret = util.clientSecret(devsIamServiceAccountKey);
67 |
68 | // Export the project name for downstream stacks.
69 | export const project = config.project;
70 |
--------------------------------------------------------------------------------
/gcp/01-identity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-gcp-identity",
3 | "devDependencies": {
4 | "@types/node": "latest"
5 | },
6 | "dependencies": {
7 | "@pulumi/gcp": "latest",
8 | "@pulumi/pulumi": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/gcp/01-identity/util.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 | import * as gcp from "@pulumi/gcp";
17 |
18 | export function bindToRole(
19 | name: string,
20 | sa: gcp.serviceAccount.Account,
21 | args: { project: pulumi.Input; roles: string[]})
22 | {
23 | args.roles.forEach((role, index) => {
24 | new gcp.projects.IAMMember(`${name}-${index}`, {
25 | project: args.project,
26 | role: role,
27 | member: sa.email.apply(email => `serviceAccount:${email}`),
28 | });
29 | })
30 | }
31 |
32 | export function createServiceAccountKey(name: string, sa: gcp.serviceAccount.Account): gcp.serviceAccount.Key {
33 | return new gcp.serviceAccount.Key(name, { serviceAccountId: sa.name });
34 | }
35 |
36 | export function clientSecret(key: gcp.serviceAccount.Key): pulumi.Output {
37 | return key.privateKey.apply(key => JSON.parse(Buffer.from(key, "base64").toString("ascii")));
38 | }
39 |
--------------------------------------------------------------------------------
/gcp/02-managed-infra/.gitignore:
--------------------------------------------------------------------------------
1 | /.pulumi/
2 | /.vscode/
3 | bin/
4 | node_modules/
5 | *.pyc
6 | .Python
7 | include/
8 | lib/
9 | yarn.lock
10 | yarn-error.log
11 | package-lock.json
12 | Pulumi.*.yaml
13 | .idea/
14 | *.iml
15 |
16 | infra-ci-client-secret.json
17 | k8s-app-dev-ci-client-secret.json
18 |
--------------------------------------------------------------------------------
/gcp/02-managed-infra/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-gcp-infra
2 | description: Creates an managed infrastructure stack for an GCP GKE cluster.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/gcp/02-managed-infra/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/gcp/02-managed-infra/README.md)
2 |
3 | # Managed Infrastructure - GCP
4 |
5 | Create the Managed Infrastructure resources to deploy GKE.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/managed-infra)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Configure the stack.
35 |
36 | ```bash
37 | $ pulumi config set gcp:zone us-west1-a
38 | $ pulumi config set gcp:project
39 | ```
40 |
41 | 1. Update the stack.
42 |
43 | ```bash
44 | $ pulumi up
45 | ```
46 |
47 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
48 |
49 | ```bash
50 | $ pulumi destroy --yes
51 | $ pulumi stack rm --yes
52 | ```
53 |
--------------------------------------------------------------------------------
/gcp/02-managed-infra/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 | import * as gcp from "@pulumi/gcp";
17 | import * as k8s from "@pulumi/kubernetes";
18 | import * as random from "@pulumi/random";
19 |
20 | const projectName = pulumi.getProject();
21 |
22 | // Create a new network.
23 | const network = new gcp.compute.Network(projectName, {
24 | autoCreateSubnetworks: false,
25 | });
26 | export const networkName = network.name;
27 |
28 | // Create a new subnet.
29 | const subnet = new gcp.compute.Subnetwork(projectName, {
30 | ipCidrRange: "10.0.0.0/24",
31 | network: network.name,
32 | secondaryIpRanges: [{ rangeName: "pods", ipCidrRange: "10.1.0.0/16" }],
33 | });
34 | export const subnetworkName = subnet.name;
35 |
--------------------------------------------------------------------------------
/gcp/02-managed-infra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-gcp-infra",
3 | "devDependencies": {
4 | "@types/node": "latest"
5 | },
6 | "peerDependencies": {
7 | "@pulumi/gke": "latest"
8 | },
9 | "dependencies": {
10 | "@pulumi/gcp": "latest",
11 | "@pulumi/kubernetes": "latest",
12 | "@pulumi/pulumi": "latest",
13 | "@pulumi/random": "latest"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/gcp/03-cluster-configuration/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-gke-cluster
2 | description: Creates a GKE cluster using best-practices.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/gcp/03-cluster-configuration/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/gcp/03-cluster-configuration/README.md)
2 |
3 | # Cluster Configuration - GCP
4 |
5 | Create the GKE Cluster and Kubernetes Defaults.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/control-plane)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-gcp-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/gcp/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-gcp-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set gcp:zone us-west1-a
55 | $ pulumi config set gcp:project
56 | $ pulumi config set k8s-gke-cluster:identityStackRef myUser/k8s-gcp-identity/dev-1573589109
57 | $ pulumi config set k8s-gke-cluster:infraStackRef myUser/k8s-gcp-infra/dev-1573589378
58 | ```
59 |
60 | 1. Update the stack.
61 |
62 | ```bash
63 | $ pulumi up
64 | ```
65 |
66 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
67 |
68 | ```bash
69 | $ pulumi destroy --yes
70 | $ pulumi stack rm --yes
71 | ```
72 |
--------------------------------------------------------------------------------
/gcp/03-cluster-configuration/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | const identityStackName = new pulumi.StackReference(pulumiConfig.require("identityStackName"));
6 | const infraStackName = new pulumi.StackReference(pulumiConfig.require("infraStackName"));
7 |
8 | export const config = {
9 | adminsIamServiceAccountSecret: identityStackName.requireOutput("adminsIamServiceAccountSecret"),
10 | devsIamServiceAccountSecret: identityStackName.requireOutput("devsIamServiceAccountSecret"),
11 | project: identityStackName.requireOutput("project"),
12 | adminsAccountId: identityStackName.requireOutput("adminsAccountId"),
13 | devsAccountId: identityStackName.requireOutput("devsAccountId"),
14 | networkName: infraStackName.requireOutput("networkName"),
15 | subnetworkName: infraStackName.requireOutput("subnetworkName"),
16 | };
17 |
--------------------------------------------------------------------------------
/gcp/03-cluster-configuration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-gke-cluster",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest",
6 | "@types/which": "latest"
7 | },
8 | "dependencies": {
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/gcp": "latest",
11 | "@pulumi/pulumi": "latest",
12 | "@pulumi/random": "latest"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/gcp/03-cluster-configuration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/gcp/04-cluster-services/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pulumi/kubernetes-guides/a29612928c8082516bac34eb4b57ed2a3cdde9df/gcp/04-cluster-services/README.md
--------------------------------------------------------------------------------
/gcp/05-app-services/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-gke-apps-svcs
2 | description: Deploys common GKE app services.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/gcp/05-app-services/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/gcp/05-app-services/README.md)
2 |
3 | # App Services - GCP
4 |
5 | Deploy App Services in the GKE Cluster.
6 |
7 | Check out the [Crosswalk Guide](https://www.pulumi.com/docs/guides/crosswalk/kubernetes/app-services)
8 | on this stack for more details.
9 |
10 | ## Deploying the Stack
11 |
12 | To deploy your infrastructure, follow the below steps.
13 |
14 | ### Prerequisites
15 |
16 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
17 |
18 | ### Steps
19 |
20 | After cloning this repo, from this working directory, run these commands:
21 |
22 | 1. Install the required Node.js packages:
23 |
24 | ```bash
25 | $ npm install
26 | ```
27 |
28 | 1. Create a new stack, which is an isolated deployment target for this example:
29 |
30 | ```bash
31 | $ pulumi stack init
32 | ```
33 |
34 | 1. Collect any stack configuration references to configure the stack in the
35 | next step.
36 |
37 | To get the Pulumi Stack Reference of a dependent stack, reference it in the
38 | config using the format: `//` e.g. `myUser/myProject/dev01`
39 |
40 | You can retrieve the Stack's reference name by running `pulumi stack ls` in
41 | the stack, and extracting it's stack URI.
42 |
43 | The stack reference for the example below is: `myUser/k8s-gcp-identity/dev-1573587501`
44 |
45 | ```bash
46 | user@pulumi:~/pulumi/kubernetes-guides/gcp/01-identity$ pul stack ls
47 | NAME LAST UPDATE RESOURCE COUNT URL
48 | dev-1573587501* 4 minutes ago 13 https://app.pulumi.com/myUser/k8s-gcp-identity/dev-1573587501
49 | ```
50 |
51 | 1. Configure the stack.
52 |
53 | ```bash
54 | $ pulumi config set gcp:zone us-west1-a
55 | $ pulumi config set gcp:project
56 | $ pulumi config set k8s-gke-apps-svcs:identityStackRef myUser/k8s-gcp-identity/dev-1573589109
57 | $ pulumi config set k8s-gke-apps-svcs:clusterStackRef myUser/k8s-gke-cluster/dev-1573601751
58 | ```
59 |
60 | 1. Update the stack.
61 |
62 | ```bash
63 | $ pulumi up
64 | ```
65 |
66 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
67 |
68 | ```bash
69 | $ pulumi destroy --yes
70 | $ pulumi stack rm --yes
71 | ```
72 |
--------------------------------------------------------------------------------
/gcp/05-app-services/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const identityStackRef = new pulumi.StackReference(pulumiConfig.require("identityStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | project: identityStackRef.requireOutput("project"),
12 |
13 | // Cluster
14 | kubeconfig: clusterStackRef.requireOutput("kubeconfig"),
15 | clusterName: clusterStackRef.getOutput("clusterName"),
16 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
17 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
18 | };
19 |
--------------------------------------------------------------------------------
/gcp/05-app-services/index.ts:
--------------------------------------------------------------------------------
1 | import * as gcp from "@pulumi/gcp";
2 | import * as k8s from "@pulumi/kubernetes";
3 | import * as pulumi from "@pulumi/pulumi";
4 | import * as random from "@pulumi/random";
5 | import { config } from "./config";
6 |
7 | const projectName = pulumi.getProject();
8 |
9 | // const privateSubnetIds = config.privateSubnetIds;
10 | // const securityGroupIds = config.securityGroupIds;
11 | const clusterName = config.clusterName;
12 |
13 | // Generate a strong password for the Postgres DB.
14 | const postgresDbPassword = new random.RandomString(
15 | `${projectName}-db-password`,
16 | {
17 | length: 20,
18 | special: true,
19 | },
20 | { additionalSecretOutputs: ["result"] },
21 | ).result;
22 |
23 | // Create a Postgres DB instance.
24 | const db = new gcp.sql.DatabaseInstance("postgresdb", {
25 | project: config.project,
26 | region: "us-west1",
27 | databaseVersion: "POSTGRES_9_6",
28 | settings: { tier: "db-f1-micro" },
29 | });
30 |
31 | // Configure a new SQL user.
32 | const user = new gcp.sql.User("default", {
33 | project: config.project,
34 | instance: db.name,
35 | password: postgresDbPassword,
36 | });
37 |
38 | // Create a new k8s provider.
39 | const provider = new k8s.Provider("provider", {
40 | kubeconfig: config.kubeconfig,
41 | });
42 |
43 | // Create a Secret from the DB connection information.
44 | const dbConn = new k8s.core.v1.Secret(
45 | "postgres-db-conn",
46 | {
47 | data: {
48 | host: db.privateIpAddress.apply(addr => Buffer.from(addr).toString("base64")),
49 | port: Buffer.from("5432").toString("base64"),
50 | username: user.name.apply(user => Buffer.from(user).toString("base64")),
51 | password: postgresDbPassword.apply(pass => Buffer.from(pass).toString("base64")),
52 | },
53 | },
54 | { provider: provider },
55 | );
56 |
57 | // Create a Redis instance.
58 | const cache = new gcp.redis.Instance("redis", {
59 | tier: "STANDARD_HA",
60 | memorySizeGb: 1,
61 | redisVersion: "REDIS_3_2",
62 | });
63 |
64 | // Create a ConfigMap from the cache connection information.
65 | const cacheConn = new k8s.core.v1.ConfigMap(
66 | "postgres-db-conn",
67 | {
68 | data: {
69 | host: cache.host.apply(addr => Buffer.from(addr).toString("base64")),
70 | },
71 | },
72 | { provider: provider },
73 | );
74 |
--------------------------------------------------------------------------------
/gcp/05-app-services/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-gke-apps-svcs",
3 | "devDependencies": {
4 | "@types/node": "latest",
5 | "typescript": "^3.0.0"
6 | },
7 | "dependencies": {
8 | "@pulumi/gcp": "latest",
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/pulumi": "latest",
11 | "@pulumi/random": "latest"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/gcp/05-app-services/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-deploy-container
2 | description: Build and push image to private registry and create a Deployment from it.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/gcp/06-apps/build-deploy-container/README.md)
2 |
3 | # Build container image and push to private registry on GCP
4 |
5 | This example builds a container image of a simple Node app and pushes the image
6 | to a private registry on GCP. The image is used to create a Kubernetes
7 | Deployment.
8 |
9 | ## Deploying the App
10 |
11 | To deploy your infrastructure, follow the below steps.
12 |
13 | ### Prerequisites
14 |
15 | 1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/)
16 | 1. [Install Node.js 8.11.3](https://nodejs.org/en/download/)
17 | 1. [Install Docker](https://docs.docker.com/v17.09/engine/installation/)
18 | 1. [Configure GCP Credentials](https://www.pulumi.com/docs/intro/cloud-providers/gcp/setup/)
19 | 1. [Configure access to a Kubernetes cluster](https://kubernetes.io/docs/setup/)
20 |
21 | ### Steps
22 |
23 | After cloning this repo, from this working directory, run these commands:
24 |
25 | 1. Install the required Node.js packages:
26 |
27 | ```bash
28 | $ npm install
29 | ```
30 |
31 | 2. Create a new stack, which is an isolated deployment target for this example:
32 |
33 | ```bash
34 | $ pulumi stack init
35 | ```
36 |
37 | 3. Set the required configuration variables for this program:
38 |
39 | ```bash
40 | $ pulumi config set gcp:project [your-gcp-project-here]
41 | $ pulumi config set gcp:zone us-west1-a # Any valid GCP zone here.
42 | ```
43 |
44 | Note that you can choose different zones here.
45 |
46 | 4. Run the following command to authorize Docker to push to the GCR registry:
47 |
48 | ```bash
49 | $ gcloud auth configure-docker
50 | ```
51 |
52 | 5. Bring up the stack, which will create the cloud resources, build and push the image to the private registry,
53 | and then create a Deployment using that image.
54 |
55 | ```bash
56 | $ pulumi up
57 | ```
58 |
59 | 6. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
60 |
61 | ```bash
62 | $ pulumi destroy --yes
63 | $ pulumi stack rm --yes
64 | ```
65 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | project: infraStackRef.requireOutput("project"),
13 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
14 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
15 |
16 | // Cluster
17 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
18 | clusterName: clusterStackRef.getOutput("clusterName"),
19 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
20 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
21 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
22 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
23 | };
24 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as docker from "@pulumi/docker";
16 | import * as gcp from "@pulumi/gcp";
17 | import * as k8s from "@pulumi/kubernetes";
18 | import * as kx from "@pulumi/kubernetesx";
19 | import * as pulumi from "@pulumi/pulumi";
20 | import { config } from "./config";
21 |
22 | // Get the GCP project registry repository.
23 | const registry = gcp.container.getRegistryRepository();
24 |
25 | // Build a Docker image from a local Dockerfile context in the
26 | // './node-app' directory, and push it to the registry.
27 | const customImage = "node-app";
28 | const appImage = new docker.Image(customImage, {
29 | imageName: pulumi.interpolate`${registry.repositoryUrl}/${customImage}:v1.0.0`,
30 | build: {
31 | context: `./${customImage}`,
32 | },
33 | });
34 |
35 | // Create a k8s provider.
36 | const provider = new k8s.Provider("provider", {
37 | kubeconfig: config.kubeconfig,
38 | namespace: config.appsNamespaceName,
39 | });
40 |
41 | // Create a Deployment of the built container.
42 | const appLabels = { app: customImage };
43 | const appDeployment = new k8s.apps.v1.Deployment("app", {
44 | spec: {
45 | selector: { matchLabels: appLabels },
46 | replicas: 1,
47 | template: {
48 | metadata: { labels: appLabels },
49 | spec: {
50 | containers: [{
51 | name: customImage,
52 | image: appImage.imageName,
53 | ports: [{name: "http", containerPort: 80}],
54 | }],
55 | }
56 | },
57 | }
58 | }, { provider: provider });
59 |
60 | //
61 | // Example using kx.
62 | //
63 |
64 | // Define the Pod for the Deployment.
65 | const pb = new kx.PodBuilder({
66 | containers: [{
67 | image: appImage.imageName,
68 | ports: { "http": 80 },
69 | }],
70 | });
71 |
72 | // Create a Deployment of the Pod defined by the PodBuilder.
73 | const appDeploymentKx = new kx.Deployment("app-kx", {
74 | spec: pb.asDeploymentSpec(),
75 | }, { provider: provider });
76 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/node-app/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/node-app/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:8.9.3-alpine
2 | RUN mkdir -p /usr/src/app
3 | COPY ./app/* /usr/src/app/
4 | WORKDIR /usr/src/app
5 | RUN npm install
6 | CMD node /usr/src/app/index.js
7 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/node-app/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello, world!
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/node-app/app/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const morgan = require('morgan');
3 |
4 | const app = express();
5 | app.use(morgan('combined'));
6 |
7 | app.get('/', (req, res) => {
8 | res.sendFile(__dirname + '/index.html')
9 | });
10 |
11 | var listener = app.listen(process.env.PORT || 80, function() {
12 | console.log('listening on port ' + listener.address().port);
13 | });
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/node-app/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-helloworld",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "dependencies": {
7 | "express": "^4.14.0",
8 | "morgan": "^1.8.2"
9 | },
10 | "devDependencies": {},
11 | "author": ""
12 | }
13 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-gcp-apps-deploy-container",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/docker": "latest",
9 | "@pulumi/gcp": "latest",
10 | "@pulumi/kubernetes": "latest",
11 | "@pulumi/kubernetesx": "^0.1.0",
12 | "@pulumi/pulumi": "latest"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/gcp/06-apps/build-deploy-container/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/general-app-services/nginx-ingress-controller/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-app-svcs-nginx
2 | description: Deploys the NGINX Ingress Controller in the App Services Namespace.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/general-app-services/nginx-ingress-controller/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/general-app-services/nginx-ingress-controller/README.md)
2 |
3 | # NGINX Ingress Controller
4 |
5 | A Deployment of the [NGINX Ingress Controller][k8s-nginx].
6 |
7 | [k8s-nginx]: https://github.com/kubernetes/ingress-nginx
8 |
9 | ## Deploying the App
10 |
11 | To deploy your infrastructure, follow the below steps.
12 |
13 | ### Prerequisites
14 |
15 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
16 |
17 | ### Steps
18 |
19 | After cloning this repo, from this working directory, run these commands:
20 |
21 | 1. Install the required Node.js packages:
22 |
23 | ```bash
24 | $ npm install
25 | ```
26 |
27 | 1. Create a new stack, which is an isolated deployment target for this example:
28 |
29 | ```bash
30 | $ pulumi stack init
31 | ```
32 |
33 | 1. Configure the stack.
34 |
35 | ```bash
36 | $ pulumi config set k8s-aws-apps-svcs-nginx:infraStackRef myUser/k8s--infra/dev-1573589378
37 | $ pulumi config set k8s-aws-apps-svcs-nginx:clusterStackRef myUser/k8s--cluster/dev-1571780002
38 | ```
39 |
40 | 1. Update the stack.
41 |
42 | ```bash
43 | $ pulumi up
44 | ```
45 |
46 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
47 |
48 | ```bash
49 | $ pulumi destroy --yes
50 | $ pulumi stack rm --yes
51 | ```
52 |
--------------------------------------------------------------------------------
/general-app-services/nginx-ingress-controller/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const infraStackRef = new pulumi.StackReference(pulumiConfig.require("infraStackRef"));
8 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
9 |
10 | export const config = {
11 | // Infra
12 | privateSubnetIds: infraStackRef.getOutput("privateSubnetIds"),
13 | publicSubnetIds: infraStackRef.getOutput("publicSubnetIds"),
14 |
15 | // Cluster
16 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
17 | clusterName: clusterStackRef.getOutput("clusterName"),
18 | securityGroupIds: clusterStackRef.getOutput("securityGroupIds"),
19 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
20 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
21 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
22 | };
23 |
--------------------------------------------------------------------------------
/general-app-services/nginx-ingress-controller/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-app-svcs-nginx",
3 | "devDependencies": {
4 | "typescript": "^3.0.0",
5 | "@types/node": "latest"
6 | },
7 | "dependencies": {
8 | "@pulumi/aws": "latest",
9 | "@pulumi/kubernetes": "latest",
10 | "@pulumi/random": "latest",
11 | "@pulumi/pulumi": "latest"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/general-app-services/nginx-ingress-controller/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "lib": [
6 | "es6"
7 | ],
8 | "module": "commonjs",
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "sourceMap": true,
12 | "stripInternal": true,
13 | "experimentalDecorators": true,
14 | "pretty": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "noImplicitAny": true,
17 | "noImplicitReturns": true,
18 | "forceConsistentCasingInFileNames": true,
19 | "strictNullChecks": true
20 | },
21 | "files": [
22 | "index.ts"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/general-cluster-services/datadog-daemonset/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: k8s-apps-daemonset-datadog
2 | description: A DaemonSet that deploys DataDog on all nodes.
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/general-cluster-services/datadog-daemonset/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.pulumi.com/new?template=https://github.com/pulumi/kubernetes-guides/blob/master/general-cluster-services/datadog-daemonset/README.md)
2 |
3 | # DataDog DaemonSet
4 |
5 | A DaemonSet that deploys DataDog on all nodes.
6 |
7 | ## Deploying the App
8 |
9 | To deploy your infrastructure, follow the below steps.
10 |
11 | ### Prerequisites
12 |
13 | 1. [Get Started with Kubernetes on Pulumi](https://www.pulumi.com/docs/get-started/kubernetes/)
14 |
15 | ### Steps
16 |
17 | After cloning this repo, from this working directory, run these commands:
18 |
19 | 1. Install the required Node.js packages:
20 |
21 | ```bash
22 | $ npm install
23 | ```
24 |
25 | 2. Create a new stack, which is an isolated deployment target for this example:
26 |
27 | ```bash
28 | $ pulumi stack init
29 | ```
30 |
31 | 1. Configure the stack.
32 |
33 | ```bash
34 | $ pulumi config set k8s-apps-daemonset-datadog:clusterStackRef myUser/k8s--cluster/dev-1571780002
35 | $ pulumi config set k8s-apps-daemonset-datadog:datadogApiKey 00000000111111111222222222333333
36 | ```
37 |
38 | 1. Update the stack.
39 |
40 | ```bash
41 | $ pulumi up
42 | ```
43 |
44 | 1. Once you've finished experimenting, tear down your stack's resources by destroying and removing it:
45 |
46 | ```bash
47 | $ pulumi destroy --yes
48 | $ pulumi stack rm --yes
49 | ```
50 |
--------------------------------------------------------------------------------
/general-cluster-services/datadog-daemonset/config.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from "@pulumi/pulumi";
2 |
3 | let pulumiConfig = new pulumi.Config();
4 |
5 | // Existing Pulumi stack reference in the format:
6 | // // e.g. "myUser/myProject/dev"
7 | const clusterStackRef = new pulumi.StackReference(pulumiConfig.require("clusterStackRef"));
8 |
9 | export const config = {
10 | // Cluster
11 | kubeconfig: clusterStackRef.getOutput("kubeconfig"),
12 | clusterSvcsNamespaceName: clusterStackRef.getOutput("clusterSvcsNamespaceName"),
13 | appSvcsNamespaceName: clusterStackRef.getOutput("appSvcsNamespaceName"),
14 | appsNamespaceName: clusterStackRef.getOutput("appsNamespaceName"),
15 |
16 | // Misc
17 | datadogApiKey: pulumiConfig.require("datadogApiKey"),
18 | };
19 |
--------------------------------------------------------------------------------
/general-cluster-services/datadog-daemonset/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "k8s-apps-daemonset-datadog",
3 | "devDependencies": {
4 | "@types/node": "^8.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/pulumi": "latest",
8 | "@pulumi/kubernetes": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/general-cluster-services/datadog-daemonset/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es2016",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "experimentalDecorators": true,
9 | "pretty": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitAny": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "strictNullChecks": true
15 | },
16 | "files": [
17 | "index.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/orig/README.md:
--------------------------------------------------------------------------------
1 | # Kubernetes the Prod Way
2 |
3 | > **NOTE:** This tutorial is still a work in progress! We will remove this message when we are more
4 | > confident in its stability!
5 |
6 | **Kubernetes the Prod Way** is a tutorial, reference architecture, and collection of prod-first code
7 | examples that demonstrate industry best-practices for **using Kubernetes** in contexts where an
8 | **organization of people** must ship **production applications.**
9 |
10 | For example: in an organization, we typically expect identity (_e.g._, [AWS IAM][aws-iam], [GCP
11 | IAM][gcp-iam], [Azure AD][azure-ad]), compute (_e.g._, [EKS][eks], [GKE][gke], [AKS][aks]), storage
12 | (_e.g._, [Aurora][aurora], [Cloud SQL][cloud-sql], [CosmosDB][cosmos-db]), and networking to be
13 | provisioned and "owned" by separate people, and perhaps separate teams. But, when an app team
14 | deploys a service, we expect all of these components to work seamlessly together.
15 |
16 | **Kubernetes the Prod Way** will show you, using batteries-included examples, how to **provision**
17 | and **use** these technologies together in a way that maintains high release velocity, without
18 | sacrificing security, governance, or stability.
19 |
20 | Examples are provided for each of: **AWS, GCP, and Azure.** In the future, we will also provide
21 | examples for common on-prem technology, such as VMWare vSphere.
22 |
23 | ## Target Audience
24 |
25 | This tutorial is aimed at people who are planning to support production applications running on
26 | Kubernetes, particularly those looking for concrete guidance on how to set up infrastructure so that
27 | teams can operate quickly, effectively, and safely.
28 |
29 | ## Contents
30 |
31 | The labs in Kubernetes the Prod Way are built using [Pulumi][pulumi], a tool that allows you to
32 | provision and configure cloud infrastructure, including [Amazon Web Services][aws] (AWS), [Microsoft
33 | Azure][azure], [Google Cloud Platform][gcp] (GCP), and Kubernetes.
34 |
35 | With that said, nearly all of the lessons learned could be applied using other tools as well, and
36 | there is very little that is specific to Pulumi.
37 |
38 | Kubernetes the Prod Way is organized as a series of labs. These labs cover everything from
39 | bootstrapping IAM roles, to provisioning compute, storage, and networking, to deploying applications
40 | on top of Kubernetes.
41 |
42 | * [Prerequisites](./docs/00-prerequisites.md)
43 | * [A Production Architecture for _Teams_](./docs/01-architecture.md)
44 | * [Lab 1: Bootstrapping Identity](./docs/02-identity.md)
45 | * [Lab 2: Provisioning Environments](./docs/03-infrastructure.md)
46 | * [Lab 3: Provisioning Applications](./docs/04-app.md)
47 | * Lab 4: Setting Up CI/CD (coming soon!)
48 | * Lab 5: Configuring Standard Kubernetes Infrastructure (coming soon!)
49 | * Lab 6: Testing your infrastructure (coming soon!)
50 |
51 |
52 | [aws-iam]: https://aws.amazon.com/iam/
53 | [gcp-iam]: https://cloud.google.com/iam/
54 | [azure-ad]: https://azure.microsoft.com/en-us/services/active-directory/
55 |
56 | [eks]: https://aws.amazon.com/eks/
57 | [gke]: https://cloud.google.com/kubernetes-engine/
58 | [aks]: https://docs.microsoft.com/en-us/azure/aks/
59 |
60 | [aurora]: https://aws.amazon.com/rds/aurora/
61 | [cloud-sql]: https://cloud.google.com/sql/
62 | [cosmos-db]: https://azure.microsoft.com/en-us/services/cosmos-db/
63 |
64 | [pulumi]: https://www.pulumi.com/
65 |
66 | [aws]: https://aws.amazon.com/
67 | [azure]: https://azure.microsoft.com/en-us/
68 | [gcp]: https://cloud.google.com/
69 |
--------------------------------------------------------------------------------
/orig/aws/identity/examples/eks-admin/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: identity
2 | description: Identity definitions for production Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/aws/identity/examples/eks-admin/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as aws from "@pulumi/aws";
16 |
17 | import * as iam from "../../";
18 | import * as util from "./util";
19 |
20 | const baseline = new iam.BaselineIam("baselineIam", {
21 | groups: {
22 | // Create default EKS admins group.
23 | defineEksAdminsGroup: true,
24 | // Opt out of admin and database admin Groups.
25 | defineAdminsGroup: false,
26 | defineDatabaseAdminsGroup: false,
27 | },
28 | });
29 |
30 | //
31 | // User/role for networking CI. Networking admin.
32 | //
33 |
34 | const networkAdminCiUser = new util.BotUser("networkAdminCiUser", {
35 | groupMembership: { groups: [baseline.groups.networkAdmins!.name] },
36 | });
37 | const networkAdminCiUserKey = networkAdminCiUser.createAccessKey("networkAdminCiUser");
38 |
39 | // Export login credentials for CI/CD.
40 | export const networkAdminCiUserAccessKey = {
41 | id: networkAdminCiUserKey.id,
42 | secret: networkAdminCiUserKey.secret,
43 | };
44 |
45 | //
46 | // EKS management user. Deploys EKS, passes AWS IAM Role ARNs to EKS, so that workloads can be
47 | // correlated to AWS IAM.
48 | //
49 |
50 | const eksAdminCiUser = new util.BotUser("eksAdminCiUser", {
51 | groupMembership: {
52 | groups: [
53 | // TODO: Remove the "administrator" group when we pull VPC and security policies out and
54 | // manage them separately from the EKS package.
55 | baseline.groups.eksAdmins!.name,
56 | baseline.groups.networkAdmins!.name, // TODO: Revoke network admin.
57 | baseline.groups.useExistingIamRoles!.name, // To use pass role ARNs to k8s RoleBindings.
58 | ],
59 | },
60 | });
61 | const eksAdminCiUserKey = eksAdminCiUser.createAccessKey("eksAdminCiUser");
62 |
63 | export const eksUserCiUserAccessKey = {
64 | id: eksAdminCiUserKey.id,
65 | secret: eksAdminCiUserKey.secret,
66 | };
67 |
68 | //
69 | // Kubernetes application role. Has access to ECR.
70 | //
71 |
72 | const kubeAppRole = util.newRoleWithPolicies(
73 | "kubeAppRole",
74 | {
75 | description: "Infrastructure management role for CI users",
76 | assumeRolePolicy: eksAdminCiUser.user.arn.apply(util.assumeRolePolicy),
77 | },
78 | {
79 | ecrPowerUser: aws.iam.AmazonEC2ContainerRegistryPowerUser,
80 | passRole: baseline.policies.useExistingIamRoles!.arn,
81 | },
82 | );
83 | export const kubeAppRoleArn = kubeAppRole.arn;
84 |
85 | //
86 | // Export group ARNs.
87 | //
88 |
89 | export const policyArns = baseline.policies.arns();
90 | export const groupArns = baseline.groups.arns();
91 |
--------------------------------------------------------------------------------
/orig/aws/identity/examples/eks-admin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@types/node": "latest"
4 | },
5 | "dependencies": {
6 | "@pulumi/aws": "latest",
7 | "@pulumi/pulumi": "latest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/orig/aws/identity/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //
16 | // Exports from `lib/`.
17 | //
18 |
19 | export { EmployeeUser, ContractorUser, BotUser } from "./lib/common";
20 | export { baselineIamPolicyDocuments, BaselineIamPoliciesOptions } from "./lib/policies";
21 | export { BaselineIamGroupsOptions } from "./lib/groups";
22 | export { BaselineIam, BaselineIamOptions } from "./lib/baseline";
23 |
--------------------------------------------------------------------------------
/orig/aws/identity/lib/baseline.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 |
17 | import * as common from "./common";
18 | import * as groups from "./groups";
19 | import * as policies from "./policies";
20 |
21 | export type BaselineIamOptions = {
22 | policies?: policies.BaselineIamPoliciesOptions;
23 | groups?: groups.BaselineIamGroupsOptions;
24 | };
25 |
26 | export class BaselineIam extends pulumi.ComponentResource {
27 | public readonly policies: policies.BaselineIamPolicies;
28 | public readonly groups: groups.BaselineIamGroups;
29 |
30 | constructor(
31 | name: string,
32 | args: BaselineIamOptions = {},
33 | opts?: pulumi.ComponentResourceOptions,
34 | ) {
35 | super(`${common.groupName}:index:BaselineIam`, name, args, opts);
36 |
37 | const defineIamPassPolicy = args.policies && args.policies.defineUseExistingIamRolesPolicy;
38 | let defineIamPassGroup = args.groups && args.groups.defineUseExistingIamRolesGroup;
39 | defineIamPassGroup = defineIamPassGroup === undefined ? true : defineIamPassGroup;
40 |
41 | if (defineIamPassGroup === true && defineIamPassPolicy === false) {
42 | throw Error(
43 | "'defineUseExistingIamRolesGroup' can't be true when 'defineUseExistingIamRolesPolicy' is false",
44 | );
45 | }
46 |
47 | if (defineIamPassGroup === true) {
48 | args.policies = args.policies === undefined ? {} : args.policies;
49 | args.policies.defineUseExistingIamRolesPolicy = true;
50 | }
51 |
52 | this.policies = new policies.BaselineIamPolicies(name, args.policies, { parent: this });
53 |
54 | const groupsArgs = {
55 | ...args.groups,
56 | useExistingIamRolesPolicy: this.policies.useExistingIamRoles,
57 | };
58 | this.groups = new groups.BaselineIamGroups(name, groupsArgs, { parent: this });
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/orig/aws/identity/lib/common.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as aws from "@pulumi/aws";
16 | import * as pulumi from "@pulumi/pulumi";
17 |
18 | //
19 | // Global statics.
20 | //
21 |
22 | export const groupName = "awsProd";
23 |
24 | //
25 | // Policy helpers.
26 | //
27 |
28 | export type Policies = { [name: string]: pulumi.Input };
29 |
30 | //
31 | // User types.
32 | //
33 |
34 | // EmployeeUser represents an AWS IAM User that is a full-time employee.
35 | export class EmployeeUser extends aws.iam.User {
36 | /**
37 | * Create a EmployeeUser resource with the given unique name, arguments, and options.
38 | *
39 | * Because it is useful to quickly distinguish between various types of users, all EmployeeUsers
40 | * are allocated names of the form `employee.${name}`.
41 | *
42 | * @param name The _unique_ name of the resource.
43 | * @param args The arguments to use to populate this resource's properties.
44 | * @param opts A bag of options that control this resource's behavior.
45 | */
46 | constructor(name: string, args?: aws.iam.UserArgs, opts?: pulumi.CustomResourceOptions) {
47 | super(`employee.${name}`, args, opts);
48 | }
49 | }
50 |
51 | // ContractorUser represents an AWS IAM User that is a contracting employee.
52 | export class ContractorUser extends aws.iam.User {
53 | /**
54 | * Create a ContractorUser resource with the given unique name, arguments, and options.
55 | *
56 | * Because it is useful to quickly distinguish between various types of users, all
57 | * ContractorUsers are allocated names of the form `contractor.${name}`.
58 | *
59 | * @param name The _unique_ name of the resource.
60 | * @param args The arguments to use to populate this resource's properties.
61 | * @param opts A bag of options that control this resource's behavior.
62 | */
63 | constructor(name: string, args?: aws.iam.UserArgs, opts?: pulumi.CustomResourceOptions) {
64 | super(`contractor.${name}`, args, opts);
65 | }
66 | }
67 |
68 | // BotUser represents an AWS IAM User that is a bot, such as a CI system.
69 | export class BotUser extends aws.iam.User {
70 | /**
71 | * Create a BotUser resource with the given unique name, arguments, and options.
72 | *
73 | * Because it is useful to quickly distinguish between various types of users, all BotUsers are
74 | * allocated names of the form `bot.${name}`.
75 | *
76 | * @param name The _unique_ name of the resource.
77 | * @param args The arguments to use to populate this resource's properties.
78 | * @param opts A bag of options that control this resource's behavior.
79 | */
80 | constructor(name: string, args?: aws.iam.UserArgs, opts?: pulumi.CustomResourceOptions) {
81 | super(`bot.${name}`, args, opts);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/orig/aws/identity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@types/node": "latest",
4 | "tslint": "^5.11.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/aws": "latest",
8 | "@pulumi/pulumi": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/orig/aws/infrastructure/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: infrastructure
2 | description: Infrastructure (compute, storage, networking) for production Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/aws/infrastructure/config.ts:
--------------------------------------------------------------------------------
1 | import * as aws from "@pulumi/aws";
2 | import * as eks from "@pulumi/eks";
3 | import * as pulumi from "@pulumi/pulumi";
4 |
5 | const config = new pulumi.Config();
6 |
7 | function getList(name: string): string[] | undefined {
8 | const str = config.get(name);
9 | return str ? str.split(",") : undefined;
10 | }
11 |
12 | /**
13 | * The VPC in which to create infrastructure resources. If left unset, a VPC will be created.
14 | */
15 | export const vpcId = config.get("vpcId");
16 |
17 | /**
18 | * The public subnets in the VPC to attach to the EKS cluster and other resources.
19 | */
20 | export const publicSubnetIds = getList("publicSubnetIds");
21 |
22 | /**
23 | * The private subnets in the VPC to attach to the EKS cluster and other resources.
24 | */
25 | export const privateSubnetIds = getList("privateSubnetIds");
26 |
27 | /**
28 | * When creating a VPC, whether or not to create private and public subnets. Defaults to false.
29 | */
30 | export const usePrivateSubnets = config.getBoolean("usePrivateSubnets");
31 |
32 | /**
33 | * When creating a VPC, the number of availability zones in which to create subnets. Defaults to 2.
34 | */
35 | export const numberOfAvailabilityZones = config.getNumber("numberOfAvailabilityZones");
36 |
37 | /**
38 | * The instance type for the cluster's worker nodes. Defaults to "t2.medium".
39 | */
40 | export const instanceType = config.get("instanceType");
41 |
42 | /**
43 | * The public key (if any) for the cluster's worker nodes. Setting this will enable SSH access to these nodes.
44 | */
45 | export const publicKey = config.get("publicKey");
46 |
47 | /**
48 | * The desired capacity of the autoscaling group that manages the cluster's worker nodes. Defaults to 2.
49 | */
50 | export const desiredCapacity = config.getNumber("desiredCapacity");
51 |
52 | /**
53 | * The minimum capacity of the autoscaling group that manages the cluster's worker nodes. Defaults to 1.
54 | */
55 | export const minSize = config.getNumber("minSize");
56 |
57 | /**
58 | * The maximum capacity of the autoscaling group that manages the cluster's worker nodes. Defaults to 2.
59 | */
60 | export const maxSize = config.getNumber("maxSize");
61 |
62 | /**
63 | * The storage class to create. Defaults to "gp2".
64 | */
65 | export const storageClass = config.get("storageClasses");
66 |
67 | /**
68 | * The name of the identity stack to use for this cluster.
69 | */
70 | export const identityStack = config.require("identityStackName");
71 |
--------------------------------------------------------------------------------
/orig/aws/infrastructure/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as awsinfra from "@pulumi/aws-infra";
16 | import * as eks from "@pulumi/eks";
17 | import * as pulumi from "@pulumi/pulumi";
18 | import * as config from "./config";
19 |
20 | // Create a VPC for the EKS cluster and its nodes if necessary.
21 | let vpcId: pulumi.Input = config.vpcId!;
22 | let publicSubnetIds: pulumi.Input[] = config.publicSubnetIds!;
23 | let privateSubnetIds: pulumi.Input[] = config.privateSubnetIds!;
24 | if (config.vpcId === undefined) {
25 | const network = new awsinfra.Network("network", {
26 | usePrivateSubnets: config.usePrivateSubnets,
27 | numberOfAvailabilityZones: config.numberOfAvailabilityZones,
28 | });
29 | vpcId = network.vpcId;
30 | publicSubnetIds = network.publicSubnetIds;
31 | privateSubnetIds = config.usePrivateSubnets ? network.subnetIds : undefined;
32 | }
33 |
34 | // Import the identity stack for its roles.
35 | const identityStack = new pulumi.StackReference("identityStack", { name: config.identityStack });
36 | const kubeAppRole = identityStack.getOutput("kubeAppRoleArn");
37 | kubeAppRole.apply(role => {
38 | if (role === undefined) {
39 | throw Error(`Stack output ${identityStack}.kubeAppRoleArn is undefined`);
40 | }
41 | });
42 |
43 | // Create the EKS cluster itself.
44 | const eksCluster = new eks.Cluster("eksCluster", {
45 | vpcId: vpcId,
46 | subnetIds: [...publicSubnetIds, ...(privateSubnetIds || [])],
47 | roleMappings: [
48 | // TODO: Find a slightly more restrictive permission for this.
49 | {
50 | roleArn: kubeAppRole,
51 | username: kubeAppRole,
52 | groups: ["system:masters"],
53 | },
54 | ],
55 | instanceType: config.instanceType,
56 | nodePublicKey: config.publicKey,
57 | desiredCapacity: config.desiredCapacity,
58 | minSize: config.minSize,
59 | maxSize: config.maxSize,
60 | storageClasses: config.storageClass,
61 | });
62 |
63 | export const kubeconfig = eksCluster.kubeconfig;
64 |
--------------------------------------------------------------------------------
/orig/aws/infrastructure/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@types/node": "latest"
4 | },
5 | "dependencies": {
6 | "@pulumi/aws": "latest",
7 | "@pulumi/aws-infra": "latest",
8 | "@pulumi/eks": "latest",
9 | "@pulumi/pulumi": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/orig/aws/infrastructure/scripts/deploy-with-ci-user.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o nounset -o errexit -o pipefail
3 |
4 | if [ $# -eq 0 ]; then
5 | echo "Usage: $0 "
6 | echo " First argument should be the name of your AWS identity stack"
7 | exit 1
8 | fi
9 |
10 | # Use EKS management user account.
11 | export AWS_ACCESS_KEY_ID="$(pulumi stack output --stack "$1" eksCiUserAccessKeyId)"
12 | export AWS_SECRET_ACCESS_KEY="$(pulumi stack output --stack "$1" eksCiUserAccessKeySecret)"
13 |
14 | pulumi up --yes
15 |
--------------------------------------------------------------------------------
/orig/azure/identity/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | /node_modules/
3 | Pulumi.*.yaml
4 |
--------------------------------------------------------------------------------
/orig/azure/identity/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: identity
2 | description: Identity definitions for production Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/azure/identity/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 | import * as random from "@pulumi/random";
17 |
18 | const config = new pulumi.Config();
19 |
20 | //
21 | // AKS-specific config.
22 | //
23 |
24 | export const name = config.get("name") || "aks";
25 | export const location = config.get("location") || "West US 2";
26 | export const password =
27 | config.get("password") ||
28 | new random.RandomString("password", {
29 | length: 16,
30 | special: true,
31 | }).result;
32 |
--------------------------------------------------------------------------------
/orig/azure/identity/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as azure from "@pulumi/azure";
16 | import * as config from "./config";
17 |
18 | let resourceGroup = new azure.core.ResourceGroup(config.name, { location: config.location });
19 |
20 | // Create the AD service principal for the K8s cluster.
21 | let adApp = new azure.ad.Application(`${config.name}-app`);
22 | let adSp = new azure.ad.ServicePrincipal(`${config.name}-sp`, {
23 | applicationId: adApp.applicationId,
24 | });
25 | let adSpPassword = new azure.ad.ServicePrincipalPassword(`${config.name}-password`, {
26 | servicePrincipalId: adSp.id,
27 | value: config.password,
28 | endDate: "2099-01-01T00:00:00Z",
29 | });
30 |
31 | //
32 | // Export required properties for downstream stacks.
33 | //
34 |
35 | export const resourceGroupName = resourceGroup.name;
36 | export const applicationID = adApp.applicationId;
37 | export const servicePrincipalPassword = adSpPassword.value;
38 | export const location = config.location;
39 |
--------------------------------------------------------------------------------
/orig/azure/identity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@types/node": "latest"
4 | },
5 | "dependencies": {
6 | "@pulumi/azure": "^0.16.5",
7 | "@pulumi/pulumi": "^0.16.7",
8 | "@pulumi/random": "^0.2.0"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/orig/azure/infrastructure/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | /node_modules/
3 | Pulumi.*.yaml
4 |
--------------------------------------------------------------------------------
/orig/azure/infrastructure/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: infrastructure
2 | description: Infrastructure (compute, storage, networking) for production Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/azure/infrastructure/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 |
17 | const config = new pulumi.Config();
18 |
19 | export const identityStackName = config.require("identityStackName");
20 | const identityStack = new pulumi.StackReference(identityStackName);
21 | //
22 | // Azure-specific config.
23 | //
24 |
25 | export const resourceGroupName = identityStack.getOutput("resourceGroupName");
26 | export const location = identityStack.getOutput("location");
27 | export const applicationID = identityStack.getOutput("applicationID");
28 | export const servicePrincipalPassword = identityStack.getOutput("servicePrincipalPassword");
29 |
30 | //
31 | // AKS-specific config.
32 | //
33 |
34 | export const nodeCount = config.getNumber("nodeCount") || 2;
35 | export const nodeSize = config.get("nodeSize") || "Standard_D2_v2";
36 | export const sshPublicKey = config.require("sshPublicKey");
37 |
--------------------------------------------------------------------------------
/orig/azure/infrastructure/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as azure from "@pulumi/azure";
16 | import * as pulumi from "@pulumi/pulumi";
17 | import * as config from "./config";
18 |
19 | // Now allocate an AKS cluster.
20 | const k8sCluster = new azure.containerservice.KubernetesCluster("aksCluster", {
21 | resourceGroupName: config.resourceGroupName,
22 | location: config.location,
23 | agentPoolProfile: {
24 | name: "aksagentpool",
25 | count: config.nodeCount,
26 | vmSize: config.nodeSize,
27 | },
28 | dnsPrefix: `${pulumi.getStack()}-kube`,
29 | linuxProfile: {
30 | adminUsername: "aksuser",
31 | sshKeys: [
32 | {
33 | keyData: config.sshPublicKey,
34 | },
35 | ],
36 | },
37 | servicePrincipal: {
38 | clientId: config.applicationID,
39 | clientSecret: config.servicePrincipalPassword,
40 | },
41 | });
42 |
43 | //
44 | // Export required properties for downstream stacks.
45 | //
46 |
47 | export const kubeconfig = k8sCluster.kubeConfigRaw;
48 |
--------------------------------------------------------------------------------
/orig/azure/infrastructure/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@types/node": "latest"
4 | },
5 | "dependencies": {
6 | "@pulumi/azure": "^0.16.5",
7 | "@pulumi/kubernetes": "^0.18.0",
8 | "@pulumi/pulumi": "^0.16.7"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/orig/docs/00-prerequisites.md:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 |
3 | This tutorial leverages [Pulumi][pulumi] and [Node.js][nodejs] to provision and configure
4 | infrastructure on AWS, Azure, or GCP. Pulumi is a platform for building and deploying cloud
5 | infrastructure and applications in your favorite language on any cloud. This particular tutorial is
6 | written in [TypeScript][ts], a strict superset of JavaScript that allows users to add optional type
7 | hints to variables. (Pulumi also supports Python and nothing in principle prevents using that
8 | instead.)
9 |
10 | ## Pulumi CLI
11 |
12 | To begin, you should [install the Pulumi CLI][pulumi-cli]. By default, the Pulumi CLI uses the
13 | Pulumi service to coordinate concurrent updates, so you should also [create an account][pulumi].
14 |
15 | It is possible to avoid a dependency on the service by using the [local backend][local-backend].
16 | But, for the purposes of this tutorial, it is much more convenient to use the service, and the
17 | entire tutorial can be completed using only the free tier.
18 |
19 | ## Yarn CLI
20 |
21 | If this is your first time writing a Node.js application, you'll need to install either Yarn or npm,
22 | which are package managers for Node.js applications. You can install it by following [the official
23 | instructions][yarn].
24 |
25 | ## Cloud Provider CLI
26 |
27 | This tutorial provides code samples for AWS, Azure and GCP. You will need to create an account for
28 | one of those providers, and then install the official CLI. For details, consult our installation
29 | guides:
30 |
31 | * [AWS][aws-setup]
32 | * [Azure][azure-setup]
33 | * [GCP][gcp-setup]
34 |
35 | ## `kubectl`, the Kubernetes CLI
36 |
37 | Pulumi will help to provision cloud resources, including those running on Kubernetes. To interact
38 | with the cluster, it will be useful to install `kubectl`, the official Kubernetes CLI. See official
39 | instructions [here][kubectl].
40 |
41 |
42 | [pulumi]: https://www.pulumi.com/
43 | [nodejs]: https://nodejs.org/en/
44 | [pulumi-cli]: https://pulumi.io/quickstart/install.html
45 | [local-backend]: https://pulumi.io/reference/state.html
46 | [ts]: https://www.typescriptlang.org/
47 | [yarn]: https://yarnpkg.com/en/docs/install
48 |
49 | [aws-setup]: https://pulumi.io/quickstart/aws/setup.html
50 | [azure-setup]: https://pulumi.io/quickstart/azure/setup.html
51 | [gcp-setup]: https://pulumi.io/quickstart/gcp/setup.html
52 |
53 | [kubectl]: https://kubernetes.io/docs/tasks/tools/install-kubectl/
54 |
--------------------------------------------------------------------------------
/orig/docs/images/app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pulumi/kubernetes-guides/a29612928c8082516bac34eb4b57ed2a3cdde9df/orig/docs/images/app.png
--------------------------------------------------------------------------------
/orig/docs/images/identity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pulumi/kubernetes-guides/a29612928c8082516bac34eb4b57ed2a3cdde9df/orig/docs/images/identity.png
--------------------------------------------------------------------------------
/orig/docs/images/infrastructure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pulumi/kubernetes-guides/a29612928c8082516bac34eb4b57ed2a3cdde9df/orig/docs/images/infrastructure.png
--------------------------------------------------------------------------------
/orig/docs/images/kube-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pulumi/kubernetes-guides/a29612928c8082516bac34eb4b57ed2a3cdde9df/orig/docs/images/kube-arch.png
--------------------------------------------------------------------------------
/orig/gcp/identity/.gitignore:
--------------------------------------------------------------------------------
1 | /.pulumi/
2 | /.vscode/
3 | bin/
4 | node_modules/
5 | *.pyc
6 | .Python
7 | include/
8 | lib/
9 | yarn.lock
10 | yarn-error.log
11 | package-lock.json
12 | Pulumi.*.yaml
13 | .idea/
14 | *.iml
15 |
16 | infra-ci-client-secret.json
17 | k8s-app-dev-ci-client-secret.json
18 |
--------------------------------------------------------------------------------
/orig/gcp/identity/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: identity
2 | description: Identity definitions for production Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/gcp/identity/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import { Config } from "@pulumi/pulumi";
16 |
17 | //
18 | // GCP-specific config.
19 | //
20 |
21 | // project is the GCP project you are going to deploy to.
22 | export const project = new Config("gcp").require("project");
23 |
--------------------------------------------------------------------------------
/orig/gcp/identity/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as gcp from "@pulumi/gcp";
16 |
17 | import * as config from "./config";
18 | import * as util from "./util";
19 |
20 | //
21 | // Assign infrastructure CI service account Cloud SQL and GKE cluster admin privileges -- i.e.,
22 | // privileges to add/delete these things, but not privileges to change apps inside.
23 | //
24 |
25 | const infraCiId = "infraCi";
26 |
27 | const infraCi = new gcp.serviceAccount.Account(infraCiId, {
28 | project: config.project,
29 | accountId: "infra-ci",
30 | displayName: "Infrastructure CI account",
31 | });
32 |
33 | const infraCiClusterAdminRole = util.bindToRole(`${infraCiId}ClusterAdmin`, infraCi, {
34 | project: config.project,
35 | role: "roles/container.clusterAdmin",
36 | });
37 |
38 | const infraCiCloudSqlAdminRole = util.bindToRole(`${infraCiId}CloudSqlAdmin`, infraCi, {
39 | project: config.project,
40 | role: "roles/cloudsql.admin",
41 | });
42 |
43 | const infraCiKey = util.createCiKey(`${infraCiId}Key`, infraCi);
44 |
45 | // Export client secret so that CI/CD systems can authenticate as this service account.
46 | export const infraCiClientSecret = util.clientSecret(infraCiKey);
47 |
48 | //
49 | // Assign application CI service account container developer privileges -- i.e., privileges to
50 | // change anything in GKE, but not to delete/add GKE clusters.
51 | //
52 |
53 | const k8sAppDevCiId = "k8sAppDev";
54 |
55 | const k8sAppDevCi = new gcp.serviceAccount.Account(k8sAppDevCiId, {
56 | project: config.project,
57 | accountId: "k8s-app-dev-ci",
58 | displayName: "Infrastructure CI account",
59 | });
60 |
61 | const k8sAppDevRole = util.bindToRole(k8sAppDevCiId, k8sAppDevCi, {
62 | project: config.project,
63 | role: "roles/container.developer",
64 | });
65 |
66 | const k8sAppDevCiKey = util.createCiKey(`${k8sAppDevCiId}Key`, k8sAppDevCi);
67 |
68 | // Export client secret so that CI/CD systems can authenticate as this service account.
69 | export const k8sAppDevCiClientSecret = util.clientSecret(k8sAppDevCiKey);
70 |
71 | //
72 | // Export project name for downstream stacks.
73 | //
74 |
75 | export const project = config.project;
76 |
--------------------------------------------------------------------------------
/orig/gcp/identity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@types/node": "latest"
4 | },
5 | "dependencies": {
6 | "@pulumi/gcp": "^0.16.2",
7 | "@pulumi/pulumi": "^0.16.6"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/orig/gcp/identity/util.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 | import * as gcp from "@pulumi/gcp";
17 |
18 | export function bindToRole(
19 | name: string,
20 | sa: gcp.serviceAccount.Account,
21 | args: { project: pulumi.Input; role: pulumi.Input },
22 | ): gcp.projects.IAMBinding {
23 | return new gcp.projects.IAMBinding(name, {
24 | project: args.project,
25 | role: args.role,
26 | members: [sa.email.apply(email => `serviceAccount:${email}`)],
27 | });
28 | }
29 |
30 | export function createCiKey(name: string, sa: gcp.serviceAccount.Account): gcp.serviceAccount.Key {
31 | return new gcp.serviceAccount.Key(name, { serviceAccountId: sa.name });
32 | }
33 |
34 | export function clientSecret(key: gcp.serviceAccount.Key): pulumi.Output {
35 | return key.privateKey.apply(key => JSON.parse(Buffer.from(key, "base64").toString("ascii")));
36 | }
37 |
--------------------------------------------------------------------------------
/orig/gcp/infrastructure/.gitignore:
--------------------------------------------------------------------------------
1 | /.pulumi/
2 | /.vscode/
3 | bin/
4 | node_modules/
5 | *.pyc
6 | .Python
7 | include/
8 | lib/
9 | yarn.lock
10 | yarn-error.log
11 | package-lock.json
12 | Pulumi.*.yaml
13 | .idea/
14 | *.iml
15 |
16 | infra-ci-client-secret.json
17 | k8s-app-dev-ci-client-secret.json
18 |
--------------------------------------------------------------------------------
/orig/gcp/infrastructure/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: infrastructure
2 | description: Infrastructure (compute, storage, networking) for production Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/gcp/infrastructure/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 |
17 | const config = new pulumi.Config();
18 |
19 | export const identityStackName = config.require("identityStackName");
20 | const identityStack = new pulumi.StackReference(identityStackName);
21 |
22 | //
23 | // GCP-specific config.
24 | //
25 |
26 | // project is the GCP project you are going to deploy to.
27 | export const project = identityStack.getOutput("project");
28 |
29 | // zone is the zone in which to build the cluster.
30 | export const zone = new pulumi.Config("gcp").get("zone");
31 |
32 | //
33 | // Kubernetes-specific config.
34 | //
35 |
36 | // envName is the name of the environment represented by this cluster.
37 | export const envName = config.require("envName");
38 |
39 | // nodeCount is the number of cluster nodes to provision. Defaults to 5 if unspecified.
40 | export const nodeCount = config.getNumber("nodeCount");
41 |
42 | // nodeMachineType is the machine type to use for cluster nodes. Defaults to n1-standard-1 if unspecified.
43 | // See https://cloud.google.com/compute/docs/machine-types for more details on available machine types.
44 | export const nodeMachineType = config.get("nodeMachineType");
45 |
--------------------------------------------------------------------------------
/orig/gcp/infrastructure/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pulumi/gke",
3 | "devDependencies": {
4 | "@types/node": "latest"
5 | },
6 | "peerDependencies": {
7 | "@pulumi/gke": "latest"
8 | },
9 | "dependencies": {
10 | "@pulumi/gcp": "^0.16.2",
11 | "@pulumi/kubernetes": "^0.18.0",
12 | "@pulumi/pulumi": "^0.16.7",
13 | "@pulumi/random": "^0.2.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/orig/gcp/infrastructure/scripts/login-to-ci-service-account.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o nounset -o errexit -o pipefail
3 |
4 | if [ $# -eq 0 ]; then
5 | echo "Usage: $0 "
6 | echo " First argument should be the name of your GCP identity stack"
7 | exit 1
8 | fi
9 |
10 | pulumi stack output infraCiClientSecret --stack "$1" > infra-ci-client-secret.json
11 | gcloud auth activate-service-account --key-file infra-ci-client-secret.json
12 | rm infra-ci-client-secret.json
13 |
--------------------------------------------------------------------------------
/orig/services/.gitignore:
--------------------------------------------------------------------------------
1 | kubeconfig.yaml
2 |
--------------------------------------------------------------------------------
/orig/services/scripts/get-kubeconfig.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o nounset -o errexit -o pipefail
3 |
4 | if [ $# -eq 0 ]; then
5 | echo "Usage: $0 "
6 | echo " First argument should be the name of your GCP infrastructure stack"
7 | exit 1
8 | fi
9 |
10 | pulumi stack output kubeconfig --stack "$1" > kubeconfig.yaml
11 |
--------------------------------------------------------------------------------
/orig/services/scripts/login-to-ci-service-account.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o nounset -o errexit -o pipefail
3 |
4 | if [ $# -eq 0 ]; then
5 | echo "Usage: $0 "
6 | echo " First argument should be the name of your GCP identity stack"
7 | exit 1
8 | fi
9 |
10 | pulumi stack output k8sAppDevCiClientSecret --stack "$1" > k8s-app-dev-ci-client-secret.json
11 | gcloud auth activate-service-account --key-file k8s-app-dev-ci-client-secret.json
12 | rm k8s-app-dev-ci-client-secret.json
13 |
--------------------------------------------------------------------------------
/orig/services/wordpress/.gitignore:
--------------------------------------------------------------------------------
1 | /.pulumi/
2 | /.vscode/
3 | bin/
4 | node_modules/
5 | *.pyc
6 | .Python
7 | include/
8 | lib/
9 | yarn.lock
10 | yarn-error.log
11 | package-lock.json
12 | Pulumi.*.yaml
13 | .idea/
14 | *.iml
15 |
16 | infra-ci-client-secret.json
17 | k8s-app-dev-ci-client-secret.json
18 |
--------------------------------------------------------------------------------
/orig/services/wordpress/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: wordpress
2 | description: Wordpress example running on production-ready Kubernetes infrastructure
3 | runtime: nodejs
4 |
--------------------------------------------------------------------------------
/orig/services/wordpress/config.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 | import * as k8s from "@pulumi/kubernetes";
17 |
18 | const config = new pulumi.Config();
19 |
20 | const infrastructureStackName = config.require("infrastructureStackName");
21 | const infrastructureStack = new pulumi.StackReference(infrastructureStackName);
22 |
23 | export const k8sProvider = new k8s.Provider(`${infrastructureStackName}`, {
24 | kubeconfig: infrastructureStack.getOutput("kubeconfig"),
25 | });
26 |
--------------------------------------------------------------------------------
/orig/services/wordpress/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2016-2019, Pulumi Corporation.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | import * as pulumi from "@pulumi/pulumi";
16 | import * as k8s from "@pulumi/kubernetes";
17 |
18 | import * as config from "./config";
19 |
20 | // Deploy the latest version of the stable/wordpress chart.
21 | const wordpress = new k8s.helm.v2.Chart(
22 | "wpdev",
23 | {
24 | repo: "stable",
25 | version: "2.1.3",
26 | chart: "wordpress",
27 | },
28 | { providers: { kubernetes: config.k8sProvider } },
29 | );
30 |
31 | // Export the public IP for Wordpress.
32 | export const frontendIp = wordpress
33 | .getResourceProperty("v1/Service", "wpdev-wordpress", "status")
34 | .apply(status => status.loadBalancer.ingress[0].ip);
35 |
--------------------------------------------------------------------------------
/orig/services/wordpress/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pulumi/gke",
3 | "devDependencies": {
4 | "@types/node": "latest"
5 | },
6 | "dependencies": {
7 | "@pulumi/kubernetes": "^0.18.0",
8 | "@pulumi/pulumi": "^0.16.7"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/orig/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "bin",
4 | "target": "es6",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "declaration": true,
8 | "sourceMap": false,
9 | "stripInternal": true,
10 | "experimentalDecorators": true,
11 | "pretty": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "noImplicitAny": true,
14 | "noImplicitReturns": true,
15 | "forceConsistentCasingInFileNames": true,
16 | "strictNullChecks": true
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/orig/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "align": [true, "parameters", "statements"],
4 | "ban": false,
5 | "class-name": true,
6 | "comment-format": [true, "check-space"],
7 | "curly": true,
8 | "eofline": true,
9 | "file-header": [true, "Copyright 2016-2019, Pulumi Corporation."],
10 | "forin": true,
11 | "indent": [true, "spaces"],
12 | "interface-name": false,
13 | "jsdoc-format": false,
14 | "label-position": true,
15 | "member-access": false,
16 | "member-ordering": [true, "variables-before-functions"],
17 | "no-any": false,
18 | "no-arg": true,
19 | "no-bitwise": false,
20 | "no-conditional-assignment": false,
21 | "no-consecutive-blank-lines": false,
22 | "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
23 | "no-construct": true,
24 | "no-debugger": true,
25 | "no-duplicate-variable": true,
26 | "no-empty": true,
27 | "no-eval": true,
28 | "no-inferrable-types": false,
29 | "no-internal-module": true,
30 | "no-parameter-properties": false,
31 | "no-require-imports": false,
32 | "no-string-literal": false,
33 | "no-switch-case-fall-through": true,
34 | "no-trailing-whitespace": true,
35 | "no-unused-expression": true,
36 | "no-use-before-declare": false,
37 | "no-var-keyword": true,
38 | "no-var-requires": false,
39 | "object-literal-sort-keys": false,
40 | "one-line": [true, "check-open-brace", "check-whitespace"],
41 | "ordered-imports": true,
42 | "prefer-const": true,
43 | "quotemark": [true, "double", "avoid-escape"],
44 | "radix": true,
45 | "semicolon": true,
46 | "switch-default": true,
47 | "trailing-comma": [
48 | true,
49 | {
50 | "multiline": "always",
51 | "singleline": "never"
52 | }
53 | ],
54 | "triple-equals": [true, "allow-null-check"],
55 | "typedef": [
56 | false,
57 | "call-signature",
58 | "parameter",
59 | "property-declaration",
60 | "variable-declaration",
61 | "member-variable-declaration"
62 | ],
63 | "typedef-whitespace": [
64 | true,
65 | {
66 | "call-signature": "nospace",
67 | "index-signature": "nospace",
68 | "parameter": "nospace",
69 | "property-declaration": "nospace",
70 | "variable-declaration": "nospace"
71 | }
72 | ],
73 | "variable-name": [true, "check-format", "allow-leading-underscore", "ban-keywords"],
74 | "whitespace": [
75 | true,
76 | "check-branch",
77 | "check-decl",
78 | "check-module",
79 | "check-separator",
80 | "check-type"
81 | ]
82 | }
83 | }
84 |
--------------------------------------------------------------------------------