Table of contents
TL;DR Where code?
-> Here you go github.com/dirien/quick-bites
This is a very quick overview of the Random Provider from Pulumi, similar to
the Quick Bites of Cloud Engineering
videos from Laura Santamaria
(@nimbinatus)
What are Stack References?
Stack References are a very interesting concept in Pulumi. They provide a way to access the output of one stack, mostly written with the export
keyword or methods from another stack.
Let us check the quick example, in the folder 00-infrastructure
, I am going to create a DigitalOcean's managed Kubernetes Service, or DOKS. The actual Pulumi
program is written in TypeScript, to demonstrate that is doesn't matter which language you are using to reference the stack output
Swiftly done via following commands:
pulumi new digitalocean-typescript
pulumi config set digitalocean:token $DIGITALOCEAN_TOKEN --secret
pulumi up --yes --skip-preview
And the TypeScript code is:
...
let doks = new digitalocean.KubernetesCluster("k8s-cluster", {
name: "quick-bites-cluster",
...
});
...
export const kubeConfig = pulumi.secret(doks.kubeConfigs[0].rawConfig)
It may take some time to come up with the deployment but at the end you should see something like this:
Outputs:
+ kubeConfig: [secret]
Resources:
+ 1 created
Now we create the second Pulumi
program in the folder 01-kubernetes
. This one will be written in Go and deploy a simple httpbin
via a Helm chart.
To reference the stack names must be fully qualified, including the organization, project, and stack name components, in the format <org-name>/<project>/<stack>
. If you own an individual account you have to change the <org-name>
part with your account name.
For me, it would be: dirien/00-infrastructure/dev
Now lets reference it! To create the next Pulumi
program in the 01-kubernetes
folder just type following commands:
pulumi new kubernetes-go
pulumi up --yes --skip-preview
The important part of the code is, where we create StackReference object. The constructor takes as input a string in the form of <org-name>/<project>/<stack>
.
...
doks, err := pulumi.NewStackReference(ctx, "dirien/00-infrastructure/dev", nil)
if err != nil {
return err
}
provider, err := kubernetes.NewProvider(ctx, "kubernetes", &kubernetes.ProviderArgs{
Kubeconfig: doks.GetStringOutput(pulumi.String("kubeConfig")),
})
...
To test that it works, let us export the kubeConfig
into a kubeconfig.yaml
file:
cd 00-infrastructure
pulumi stack output kubeconfig --show-secrets > kubeconfig.yaml
export KUBECONFIG=kubeconfig.yaml
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpbin ClusterIP 10.245.179.59 <none> 80/TCP 43s
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 10m
kubectl port-forward svc/httpbin 8080:80
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Handling connection for 8080
Handling connection for 8080
Wrap up
What are the advantages of using Stack References?
Now you can cut your infrastructure code into separate pulumi programs, and define an opinionated way of which values you want to expose for other stacks to consume.
You created a boundary, where you can work on your own lifecycle needs. Any updates to the infrastructure code will be isolated to the other Pulumi programs.
This self-contained Pulumi programs can have different stacks (dev/staging/prod) you can provide to others.
Different Pulumi programs may be ownd from different people inside on team or whole teams inside an organization.
Application developers, don't need to know about the detail infrastructure implementation. What they need are only the endpoints. For example the kubeconfig or the database connection string.
Clean up
Don't forget to destroy both Pulumi
programs with the following command:
pulumi destroy --yes