Skip to content

Commit

Permalink
Add the Pulumi Kubernetes Operator (#141)
Browse files Browse the repository at this point in the history
* Initial pass - still need to add Helm resources.

* Fix up Flux/Helm resources.

* Remove erroneous tgz file.

* Turn tester Job to CronJob.

* Add external secret.

* Correct external secret.

* Rename HelmRepository

* Encapsulate the tester resources.
Use alpine:k8s:1.26.2 image.
Use kubectl wait rather than sleep.

---------

Co-authored-by: Eron Wright <[email protected]>
  • Loading branch information
jkodroff and EronWright authored Sep 21, 2023
1 parent e2ad87c commit b6d522c
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 0 deletions.
3 changes: 3 additions & 0 deletions eks-anywhere-common/Addons/Partner/Pulumi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Pulumi

This folder contains Kubernetes manifest that install the [Pulumi Kubernetes Operator](https://www.pulumi.com/docs/using-pulumi/continuous-delivery/pulumi-kubernetes-operator/) along with resources necessary to run the automated tests under `../Testers/Pulumi` in this repository.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: pulumi-access-token
namespace: pulumi
spec:
refreshInterval: 1m
secretStoreRef:
name: eksa-secret-store #The secret store name we have just created.
kind: ClusterSecretStore
target:
name: pulumi-access-token # Secret name in k8s
data:
- secretKey: accessToken # which key it's going to be stored in
remoteRef:
key: pulumi-access-token # External secret name goes here
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: pulumi
namespace: pulumi
spec:
interval: 10m
type: oci
url: oci://ghcr.io/pulumi/helm-charts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: pulumi
labels:
aws.conformance.vendor: pulumi
aws.conformance.vendor-solution: pulumi-kubernetes-operator
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: pulumi-kubernetes-operator
namespace: pulumi
spec:
interval: 10m
targetNamespace: pulumi
chart:
spec:
chart: pulumi-kubernetes-operator
version: "0.3.0"
sourceRef:
kind: HelmRepository
name: pulumi
187 changes: 187 additions & 0 deletions eks-anywhere-common/Testers/Pulumi/pulumi-tester-cronjob.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: pulumi-tester
namespace: pulumi
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pulumi-tester
namespace: pulumi
rules:
- apiGroups: ["pulumi.com"]
resources: ["stacks", "programs"]
verbs: ["*"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pulumi-tester
namespace: pulumi
subjects:
- kind: ServiceAccount
name: pulumi-tester
roleRef:
kind: Role
name: pulumi-tester
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pulumi-tester
namespace: pulumi
data:
pulumi-org: aws-partnership
pulumi-k8s-operator-test.sh: |-
#!/bin/bash
set -e
RANDOM_SUFFIX=$(date +%s)-$RANDOM
MANIFEST_FILENAME=/tmp/pulumi-test-stack-${RANDOM_SUFFIX}.yaml
# Create a new, unique stack name. The name of the stack must be unique for each
# run for 2 reasons:
# 1. To ensure that each test run on the current platform starts from a known
# state, free from any previously test runs.
# 2. To ensure that we don't get colliding updates as AWS runs the test
# simultaneously on different EKS-A platforms.
TEST_PULUMI_STACK_NAME=test-${RANDOM_SUFFIX}
STACKPATH=${PULUMI_ORG}/eks-pulumi-operator-test/${TEST_PULUMI_STACK_NAME}
echo ""
echo "Writing out test manifest file '${MANIFEST_FILENAME}'"
# Note that while we use a random Pulumi stack name within the Stack resource,
# we keep the name of the Kubernetes Stack and Program resources static. This is
# intentional. If a test fails, we don't want it to leave superfluous Stack and
# Program K8s resources behind because the operator will keep trying to
# reconcile them. (The test failed - they should never be re-run again.)
# Instead, we want to reuse the same Kubernetes resource over and over but have
# it generate a new, uniquely-named Pulumi stack.
cat << EOF > $MANIFEST_FILENAME
apiVersion: pulumi.com/v1
kind: Program
metadata:
name: eks-pulumi-operator-test
namespace: pulumi
program:
resources:
myRandomPet:
type: random:RandomPet
outputs:
petName: \${myRandomPet.id}
---
apiVersion: pulumi.com/v1
kind: Stack
metadata:
name: eks-pulumi-operator-test
namespace: pulumi
spec:
stack: ${STACKPATH}
programRef:
name: eks-pulumi-operator-test
destroyOnFinalize: true
envRefs:
PULUMI_ACCESS_TOKEN:
type: Secret
secret:
name: pulumi-access-token
key: accessToken
EOF
echo ""
echo "Deploying sample stack and program."
kubectl apply -f $MANIFEST_FILENAME
echo ""
echo "Waiting for the operator to deploy the stack."
kubectl wait -n pulumi stack/eks-pulumi-operator-test --for=condition=Ready --timeout=180s
echo ""
echo "Verifying that the stack exists."
curl \
-s \
--fail \
-H "Accept: application/vnd.pulumi+8" \
-H "Content-Type: application/json" \
-H "Authorization: token $PULUMI_ACCESS_TOKEN" \
https://api.pulumi.com/api/stacks/${STACKPATH}
echo ""
echo "Destroying K8s Stack resource"
kubectl delete -n pulumi stacks/eks-pulumi-operator-test
echo ""
echo "Waiting for the operator to remove the stack"
kubectl wait -n pulumi stack/eks-pulumi-operator-test --for=delete --timeout=180s
echo ""
echo "Verifying the stack no longer exists"
STATUSCODE=$(curl \
-s \
-o /dev/null \
--w "%{http_code}" \
-H "Accept: application/vnd.pulumi+8" \
-H "Content-Type: application/json" \
-H "Authorization: token $PULUMI_ACCESS_TOKEN" \
https://api.pulumi.com/api/stacks/${STACKPATH}
)
if test $STATUSCODE -ne 404; then
echo "ERROR: Expected HTTP status code 404 from the Pulumi Cloud API when querying the stack. Got HTTP status code $STATUSCODE instead."
false
fi
# This is for purely for running the script locally. Since the K8s tester Job is
# run in an ephemeral container, deleting the file is unnecessary in that
# context:
echo ""
echo "Deleting test manifest file '${MANIFEST_FILENAME}'"
rm ${MANIFEST_FILENAME}
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: pulumi-k8s-operator-test
namespace: pulumi
spec:
schedule: "10 10 * * *"
jobTemplate:
spec:
activeDeadlineSeconds: 900
template:
spec:
serviceAccountName: pulumi-tester
containers:
- command:
- bash
- /scripts/pulumi-k8s-operator-test.sh
image: "alpine/k8s:1.26.2"
name: script
env:
- name: PULUMI_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: pulumi-access-token
key: accessToken
- name: PULUMI_ORG
valueFrom:
configMapKeyRef:
name: pulumi-tester
key: pulumi-org
volumeMounts:
- name: pulumi-tester-configmap
mountPath: /scripts/pulumi-k8s-operator-test.sh
subPath: pulumi-k8s-operator-test.sh
readOnly: false
restartPolicy: Never
volumes:
- name: pulumi-tester-configmap
configMap:
name: pulumi-tester
defaultMode: 0777

0 comments on commit b6d522c

Please sign in to comment.