App rollout via ConfigMap data change
A Deployment that mounts a ConfigMap; updating the data in the ConfigMap triggers a rollout of the Deployment
This example lives in the pulumi/examples repository. Check out just this directory to use it:
git clone --filter=blob:none --sparse https://github.com/pulumi/examples pulumi-examplesgit -C pulumi-examples sparse-checkout set kubernetes-ts-configmap-rolloutcd pulumi-examples/kubernetes-ts-configmap-rolloutUses NGINX to reverse-proxy traffic to pulumi.github.io. The NGINX configuration is contained in
the file default.conf in this directory; this program reads that file and puts it in a
ConfigMap. Hence, changing data in that file will register as a change in the ConfigMap’s
data, which will trigger a rollout of the NGINX Deployment.

Prerequisites#
Deploying the example#
-
Create a new stack:
Terminal window pulumi stack init dev -
This example will attempt to expose the
nginxdeployment to the Internet with aServiceof typeLoadBalancer. Since minikube does not supportLoadBalancer, the application already knows to use typeClusterIPinstead; all you need to do is tell it whether you’re deploying to minikube:Terminal window pulumi config set isMinikube <value> -
Install dependencies:
Terminal window npm install -
Deploy the stack:
Terminal window pulumi upUpdating stack 'configmap-rollout-dev'Performing changes:Type Name Status Info+ pulumi:pulumi:Stack configmap-rollout-configmap-rollout-dev created+ ├─ kubernetes:core:ConfigMap nginx created+ ├─ kubernetes:apps:Deployment nginx created+ └─ kubernetes:core:Service nginx created---outputs:---frontendIp: "35.193.210.254"info: 4 changes performed:+ 4 resources createdUpdate duration: 49.612528861s -
We can see here in the
---outputs:---section that our proxy was allocated a public IP, in this case35.193.210.254. It is exported with a stack output variable,frontendIp. Usecurlandgrepto retrieve the<title>of the site the proxy points at:Terminal window curl -sL $(pulumi stack output frontendIp):80 | grep -C 1 "<title>"<title>Pulumi. Serverless // Containers // Infrastructure // Cloud // DevOps</title>
Trigger a rollout by changing the config#
Now, open default.conf and change .node.server and .server.location.proxy_set_header to point
at google.com. If you’re on macOS you can run sed -i bak "s/pulumi.github.io/google.com/g" default.conf
The result should look like this:
upstream node { server google.com;}server { listen 80; server_name _; root /usr/share/nginx/html; location / { proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header Host google.com; proxy_pass http://node; proxy_redirect off; port_in_redirect off; }}Running preview now shows that this change will cause us to replace the ConfigMap with a new one
containing the new data, and subsequently trigger a rollout in the Deployment. This is a meaningful
difference from plain kubectl, which by default will not trigger a rollout of the containers that
reference a ConfigMap when its data changes — instead the kubelet silently syncs the new data to the
containers after its TTL expires. Pulumi plans an explicit, safe rollout:
NOTE: This rollout is safe! Pulumi executes this plan with the following steps:
- Create a new
ConfigMapwith a new name and the new data.- Update the
PodTemplateof theDeploymentto point at the newConfigMap. This update triggers theDeploymentcontroller to try to roll out a new set of containers with mounts that contain this new data.- Only once that succeeds, delete the old
ConfigMap.
Previewing update of stack 'configmap-rollout-dev' Type Name Status Info * pulumi:pulumi:Stack configmap-rollout-configmap-rollout-dev no change +- ├─ kubernetes:core:ConfigMap nginx replace changes: ~ data,metadata ~ └─ kubernetes:apps:Deployment nginx update changes: ~ spec
info: 2 changes previewed: ~ 1 resource to update +-1 resource to replace 2 resources unchangedRunning pulumi up should similarly look something like this:
Updating stack 'configmap-rollout-dev' Type Name Status Info * pulumi:pulumi:Stack configmap-rollout-configmap-rollout-dev done +- ├─ kubernetes:core:ConfigMap nginx replaced changes: ~ data,metadata ~ └─ kubernetes:apps:Deployment nginx updated changes: ~ spec
---outputs:---frontendIp: "35.193.210.254"
info: 2 changes performed: ~ 1 resource updated +-1 resource replaced 2 resources unchangedUpdate duration: 5.679919856sNow, if we curl the IP address once more, we see that it points at google.com!
Note: minikube does not support type
LoadBalancer; if you are deploying to minikube, make sure to runkubectl port-forward svc/frontend 8080:80to forward the cluster port to the local machine and access the service vialocalhost:8080.
curl -sL $(pulumi stack output frontendIp) | grep -o "<title>Google</title>"<title>Google</title>Cleaning up#
Once you’re finished experimenting, you can destroy your stack and remove it to avoid incurring any additional cost:
pulumi destroypulumi stack rm