Commit 0cccf634 authored by Erin Krengel's avatar Erin Krengel
Browse files

add more comments, use defaults where applicable

parent 739ef7da
......@@ -16,15 +16,14 @@ interface AcceptanceConfig {
clusterProvider: k8s.Provider;
}
export function SetupAcceptanceTests(config: AcceptanceConfig): k8s.batch.v1.Job {
export function setupAcceptanceTests(config: AcceptanceConfig): k8s.batch.v1.Job {
const name = `${config.env}-demo-app-acc-test`;
// Create subscription on the app's topic.
// Create subscription on the app's topic and give acceptance test svc
// account permission to subscribe to the subscription.
const subscription = new gcp.pubsub.Subscription(name, {
topic: config.topic.name,
});
// Give acceptance test svc account permission to subscribe from the subscription.
new gcp.pubsub.SubscriptionIAMMember(name, {
member: `serviceAccount:${config.accSvcAccountEmail}`,
role: "roles/pubsub.subscriber",
......@@ -40,10 +39,10 @@ export function SetupAcceptanceTests(config: AcceptanceConfig): k8s.batch.v1.Job
bucket: config.bucket.name,
});
// Create a service account key for the acceptance test account.
// Create a service account key for the acceptance test service account
// and then use that key to create a K8s secret that will be mounted to
// our K8s job.
const serviceAccountKey = svcKey.getSvcKey(name, config.accSvcAccountId);
// Create a K8s secret from the service account key to mount to our K8s job.
const secret = new k8s.core.v1.Secret(name, {
metadata: {
name: `${config.env}-google-cloud-key-acc-test`,
......@@ -77,22 +76,18 @@ export function SetupAcceptanceTests(config: AcceptanceConfig): k8s.batch.v1.Job
{ name: "google-cloud-key", mountPath: "/var/secrets/google" }
]
}],
volumes: [
{
name: "google-cloud-key",
secret: { secretName: secret.metadata.name }
}
],
volumes: [{
name: "google-cloud-key",
secret: { secretName: secret.metadata.name }
}],
restartPolicy: "Never",
},
},
backoffLimit: 0,
},
},
{
provider: config.clusterProvider,
customTimeouts: { create: "5m" },
dependsOn: [config.appDeployment]
},
);
}, {
provider: config.clusterProvider,
customTimeouts: { create: "5m" },
dependsOn: [config.appDeployment]
});
}
......@@ -4,11 +4,16 @@ import * as gcp from "@pulumi/gcp";
import * as acceptance from "./acceptance";
import * as svcKey from "./svcKey";
// Get GCP project configuration value.
// Get GCP project configuration value. This allows us to set a "test"
// GCP project for our test resources and then a separate GCP project
// for production.
const gcpConfig = new pulumi.Config("gcp");
const project = gcpConfig.require("project");
// Get stack's configuration values.
// Get stack's configuration values. Using a configurable environment name,
// we can make multiple test resources in the same project without collisions.
// We use a configurable DOCKER_TAG to ensure we are testing the same immutable
// image that we will also deploy to production.
const config = new pulumi.Config("demo-app");
const ENV = config.require("ENV");
const DOCKER_TAG = config.require("DOCKER_TAG");
......@@ -20,55 +25,52 @@ const DOCKER_TAG = config.require("DOCKER_TAG");
const globalStackRef = new pulumi.StackReference("rocore/global-infra/global-infra");
const kubeconfigOutput = globalStackRef.getOutput("kubeconfig");
const namespaceOutput = globalStackRef.getOutputSync("namespace");
let svcAccountOutput = globalStackRef.getOutputSync("testSvcAccount");
const accTestSvcAccount = globalStackRef.getOutputSync("acceptanceTestSvcAccount");
// By default, we're going to use a "test" service account for our application.
// If the environment is production, we will use the production service account.
// If the environment is "prod", we will use the production service account.
let svcAccountOutput = globalStackRef.getOutputSync("testSvcAccount");
if (ENV === "prod") {
svcAccountOutput = globalStackRef.getOutputSync("prodSvcAccount");
}
// We prepend the environment to the name used for all
// resources. This allows us to run this same program multiple
// times in different environments and not have resources with
// the duplicate names.
// We prepend the environment to the name used for all resources. This
// allows us to run this same program multiple times for different test
// environments and not have resources with the duplicate names.
const name = `${ENV}-demo-app`;
// Create a Kubernetes provider from the global stack reference.
// We will use this make sure our K8s resources are created in the
// correct cluster and namespace.
const clusterProvider = new k8s.Provider(name, {
kubeconfig: kubeconfigOutput,
namespace: namespaceOutput.metadata.name,
});
// Create egress topic.
// Create egress topic and give the app's service account permission
// to publish to the topic.
export const topic = new gcp.pubsub.Topic(name);
// Give the Service permission to publish to the topic.
new gcp.pubsub.TopicIAMMember(name, {
member: `serviceAccount:${svcAccountOutput.email}`,
role: "roles/pubsub.publisher",
topic: topic.name,
}, { dependsOn: [topic] });
// Create bucket.
// Create bucket and give the app's service account permission to
// create objects in the bucket.
export const bucket = new gcp.storage.Bucket(name, {
location: "us-west1",
});
// Give the Service permission to create objects.
new gcp.storage.BucketIAMMember(name, {
member: `serviceAccount:${svcAccountOutput.email}`,
role: "roles/storage.objectCreator",
bucket: bucket.name,
});
// Create service account key.
const serviceAccountKey = svcKey.getSvcKey(name, svcAccountOutput.id);
// Create a Kubernetes provider from the global stack reference.
// We will use this make sure our K8s resources are created in the
// correct cluster and namespace.
const clusterProvider = new k8s.Provider(name, {
kubeconfig: kubeconfigOutput,
namespace: namespaceOutput.metadata.name,
});
// Create a K8s secret from the service account key to mount to our K8s deployment.
// Create a service account key for the app's service account
// and then use that key to create a K8s secret that will be mounted to
// our K8s deployment.
const serviceAccountKey = svcKey.getSvcKey(name, svcAccountOutput.id);
const secret = new k8s.core.v1.Secret(name, {
metadata: { name: `${ENV}-google-cloud-key` },
stringData: { "key.json": serviceAccountKey },
......@@ -79,43 +81,37 @@ const appLabels = { appClass: name };
const deployment = new k8s.apps.v1.Deployment(name, {
metadata: { labels: appLabels },
spec: {
replicas: 1,
selector: { matchLabels: appLabels },
template: {
metadata: { labels: appLabels },
spec: {
containers: [
{
name: name,
image: `rocore/demo-app:${DOCKER_TAG}`,
imagePullPolicy: "Always",
ports: [{ name: "http", containerPort: 8080 }],
env: [
{ name: "TOPIC", value: topic.name },
{ name: "BUCKET", value: bucket.name },
{ name: "PROJECT", value: project },
{
name: "GOOGLE_APPLICATION_CREDENTIALS",
value: "/var/secrets/google/key.json"
},
],
volumeMounts: [{
name: "google-cloud-key",
mountPath: "/var/secrets/google"
}],
readinessProbe: {
httpGet: {
path: "/ping",
port: 8080,
},
initialDelaySeconds: 3,
periodSeconds: 3,
containers: [{
name: name,
image: `rocore/demo-app:${DOCKER_TAG}`,
imagePullPolicy: "Always",
ports: [{ name: "http", containerPort: 8080 }],
env: [
{ name: "TOPIC", value: topic.name },
{ name: "BUCKET", value: bucket.name },
{ name: "PROJECT", value: project },
{
name: "GOOGLE_APPLICATION_CREDENTIALS",
value: "/var/secrets/google/key.json"
},
}
],
],
volumeMounts: [{
name: "google-cloud-key",
mountPath: "/var/secrets/google"
}],
readinessProbe: {
httpGet: { path: "/ping", port: 8080 },
initialDelaySeconds: 3,
periodSeconds: 3,
},
}],
volumes: [{
name: "google-cloud-key",
secret: { secretName: secret.metadata.name }
secret: { secretName: secret.metadata.name },
}]
}
}
......@@ -126,7 +122,6 @@ const deployment = new k8s.apps.v1.Deployment(name, {
const service = new k8s.core.v1.Service(name, {
metadata: { labels: appLabels },
spec: {
type: "ClusterIP",
ports: [{ port: 80, targetPort: 8080 }],
selector: appLabels,
},
......@@ -135,7 +130,7 @@ const service = new k8s.core.v1.Service(name, {
// If it's a test environment, set up acceptance tests.
let job: k8s.batch.v1.Job | undefined;
if (ENV.startsWith("test")) {
job = acceptance.SetupAcceptanceTests({
job = acceptance.setupAcceptanceTests({
env: ENV,
project: project,
topic: topic,
......
......@@ -17,10 +17,6 @@ import (
// MessageHandler returns a handler that stores the messages it receives.
func MessageHandler(topic *pubsub.Topic, bkt *storage.BucketHandle) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusNotFound)
return
}
ctx := r.Context()
// Read the request body.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment