Pulumi Concepts
External
Internal
Overview
Pulumi is an Infrastructure as Code platform that allows using common programming languages, tools, and frameworks, to provision, update, and manage cloud infrastructure resources. Pulumi is one of the tools that can be used to manage generic Infrastructure as Code stacks. In Pulumi, Infrastructure resources are declared in programs. Programs reside in a project. The programs are instantiated as stacks in the infrastructure platform. A stack is an isolated and configurable instance of the program.
Architecture
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/how-pulumi-works/
Organization
Other organization is also referred to as the "owner".
The list of organizations available to the user in the backend is available with pulumi org ls
.
- Relationship between a stack and an organization ("owner"). "New stack owner, some-org, does not match existing owner, o_feodorov."
Project
Local Project Representation
A project is a directory that contains one program and metadata on how to run the program, such as what runtime to use, where to look for the program, etc. The project definition metadata is maintained in Pulumi.yaml
. The presence of Pulumi.yaml
is the indication that directory is a Pulumi project.
The project's program may be applied to the infrastructure platform creating one or more independent resource sets, as defined in the program. An instantiation of a program is called a stack. The project may contain one or more stacks. Each stack is defined in the project by its stack settings file. Projects can be created with pulumi new
command. The command creates the project metadata and the first (and possibly the only one) stack, based on a template. The program and metadata are read by the Pulumi CLI and applied to the infrastructure platform with the pulumi up
command, creating a stack.
The project can be obtained programmatically. In Python, use get_project()
function.
- Is the project stored in the backend after
pulumi new
. How can it be listed?
Current Project
The current project is the project given by the nearest Pulumi.yaml file.
Project Name
Specified using the name
attribute in Pulumi.yaml
. It shows up in the Pulumi dashboard. It is used to aggregate the associated stacks and their resources underneath the project, under a simple hierarchy. Project names may only contain alphanumeric characters, hyphens, underscores and periods.
Template
A list of available templates is presented executing pulumi new
without any argument. An example is available here:
Intuitively, the right template can be invoked by using the name of the cloud and the language, example: aws-python
.
Project Layout
my-project ├─ README.md ├─ Pulumi.yaml # Project definition file ├─ Pulumi.red-stack.yaml # Stack settings file ├─ Pulumi.green-stack.yaml ├─ ... └─ ... # language-specific elements
Language-specific layouts:
Pulumi.yaml
Contains the project definition. The name must begin with a capital "P", and both "yaml" and "yaml" extensions are valid.
Example:
name: simple-aws runtime: name: python options: virtualenv: venv
description: An experimental AWS Pulumi project.
Attributes
name
Required attribute that specifies the project name.
Deploying a Project
Deploying a project means applying the project's code with the active stack configuration to the infrastructure platform, thus creating or updating infrastructure resources. Deployment is initiated via CLI with the pulumi up
command. Reconcile with What Happens when Code Is Applied to Platform?.
Project Operations
Projects on the Backend
Projects are not a first class concept on the backend, they only exist as a way to namespace stacks.
Program
A program contains code that describes how cloud infrastructure should be composed. It can be written in Python, TypeScript or Go. Infrastructure is declared by defining resource objects whose properties correspond to the desire state of the infrastructure. The properties are also used to express dependencies between resources, and can be exported outside the stack. It is recommended to group resource with common lifecycles together. Programs reside in projects.
Paths in Program
When the program references resources in the local file system, their paths must be relative to the working directory. Not the project directory, in which the program is in?
Programming Model
The Pulumi programming model defines the core concepts in use when creating infrastructure as code programs. These concepts are made available in the Pulumi SDKs, that support Python, TypeScript and Go.
Resource
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/resources/
Pulumi understands dependencies between resources and uses the relationship between resources to maximize execution parallelism and ensure correct ordering when a stack is instantiated.
Property
Difference between resource and stack inputs/outputs.
Input Property
Output Property
Stack
A stack is an isolated, independently configurable instance of a Pulumi program, materialized as a set of infrastructure resources created by executing the program against the infrastructure platform. Every program is applied to the infrastructure as one, possibly more stacks. Stacks are commonly used to denote different phases of development, such as "development", "staging" and "production", or feature branches. A project can have an arbitrary number of stacks. By default, Pulumi creates a new stack per project when pulumi new
is used. Stack creation means creation of the associated stack settings file and a stack state representation in the Pulumi backend.
Stack Name
The stack name must be unique within a project. The stack name may only contain alphanumeric characters, hyphens, underscores and periods. A fully qualified stack name includes the organization and the project name: <org-name>/<project-name>/<stack-name>
. If you are using Pulumi in your organization, and when new stacks are created, they will be created by default in your user account. To create the stack in the organization instead, name the stack using <org-name>/<stack-name>
.
Stack URI
What is the semantics of a stack URI?
Multiple Stacks per Project
When a project is created with pulumi new
, the configuration of a stack is also automatically created. Additional stack configurations can be created for an existing project with the pulumi stack init
command. Note that multiple stacks per project means that all the stacks share the same program (behavior) but have different configurations, corresponding to different stack settings files. Note that pulumi stack init
does not fully manage the corresponding stack setting file, it does create it, but it leaves it into an incomplete state.
Current (Active) Stack
When a project contains multiple stacks, one of them is active, or current, at any time. The current stack for a project can be displayed by running pulumi about
in the project, or running pulumi stack ls
, in which case the active stack will be marked with an asterisk. A stack can be set as active by running pulumi stack select
.
Stack Settings File
Each stack of a project will have a file named Pulumi.<stackname>.yaml
that contains configuration (key/value pairs) specific to the stack it is associated with. The file typically resides in the project root directory. Secret values are encrypted, which, according to the Pulumi documentation, makes them safe to be checked in into a repository. This is debatable. The stack settings for ephemeral stacks are typically not checked into source control.
A stack setting file can be created and managed with pulumi config
.
Stack Configuration
TO PROCESS when I have access to a working environment so I can try code: https://www.pulumi.com/docs/intro/concepts/config/
Namespace
Key space.
Stack Output (Exports)
A stack can be turned into a component that integrates with other components. The way Pulumi programs communicate information for external consumption and integration with other stacks is by using output, or exports. Outputs are values produced during an update and can be thought as programmatic results of a stack update, additional to the infrastructure resources created in the infrastructure platform. They are also known as "properties". They are maintained as part of the stack's state, by the backend service. If the stack was not deployed yet, no outputs are available, and the output values are resolved after pulumi up
command completes. They can be retrieved via CLI with pulumi stack output <property-name>
, displayed on the console or shared with other stacks, via stack references. Exposing an output is called "exporting". This is how it's done in Python:
import pulumi
...
pulumi.export("something", resource.someAttribute)
pulumi.export("color", "blue")
pulumi.export("details", {"shape": "square", "size": 10})
pulumi.export("whole_resource", resource)
Some resource properties are handled as secrets, and not displayed as part of the pulumi stack output
unless the --show-secrets
flag is used.
The value of a stack export can be a regular value, an Output or a Promise, effectively the same as an Input. They are JSON, though quotes are removed when exporting strings. An entire resource can be exported, and if that happens, it will be serialized as JSON. For example, if a SSM parameter is exported, it will be available as:
whole_resource {"allowed_pattern":"","arn":"arn:aws:ssm:us-west-2:999999999999:parameter/experimental/ovidiu/test2-382b9f1","data_type":"text","description":"","id":null,"key_id":"","name":"/experimental/ovidiu/test2-382b9f1","overwrite":null,"tags":{},"tags_all":{},"tier":"Standard","type":"String","urn":"urn:pulumi:ssm::blue::aws:ssm/parameter:Parameter::/experimental/ovidiu/test2","value":null,"version":1}
Stack References
Stack references are used by consumer stacks to get their dependencies, using the Stack Data Lookup pattern.
Stack Tags
Stacks have associated metadata as tags. Each tags has a name and a value. A set of built-in tags are automatically assigned and updated each time a stack is updated. Tags are only supported with the Pulumi Service backend. To view a stack's tags, run pulumi stack tag ls
. Tags are useful to group stacks in the console.
Custom tags can be applied with pulumi stack tag set <name> <value>
. Custom tags should not be prefixed with pulumi:
, gitHub:
, or vcs:
to avoid conflicting with built-in tags that are assigned and updated with fresh values each time a stack is updated.
Built-in Tags
pulumi:project
pulumi:runtime
Example of a Python runtime section.
pulumi:description
gitHub:owner
gitHub:repo
vcs:owner
vcs:repo
vcs:kind
Deploying a Stack
See Deploying a Project above.
Destroying and Deleting a Stack
Destroying a stack means releasing and deleting resources associated with the stack with pulumi destroy
. The command uses the latest configuration values, rather than the ones that were last used when the program was deployed. Pulumi waits until all resources are shut down and deleted before it considers the destroy operation to be complete.
Deleting a stack means removing all stack history from the backend and the stack configuration file Pulumi.<stack-name>.yaml
. Use pulumi rm
. A stack must be first destroyed, then deleted.
⚠️ Forcefully deleting a stack before destroying it may leave orphaned resources behind.
Ephemeral Stack
Ephemeral stacks may have stack settings files.
Stack Operations
- List stacks
- Select a stack
- Display stack resources
- Display stack tags
- Create a stack
- Select a stack
- Remove (delete) a stack
Inputs and Outputs
The Pulumi programming model includes the concepts of Input and Output values, which model how output of one resource flow in as inputs of another resource.
See stack outputs.
- TO PROCESS: https://www.pulumi.com/docs/intro/concepts/inputs-outputs/
pulumi.Output.concat(...)
Output
Input
Promise
State and Backends
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/state/
State can be interacted with via both #CLICLI and programming model.
What Happens when Code Is Applied to Platform?
The pulumi up
command evaluates the program and determines resource updates to make. Part of the update process, pulumi will run the preview step of the update, which computes the minimally disruptive change to achieve the desired state described by the program.
- Where is the code executed?
- Where does stdout/stderr go?
- Reconcile with Deploying a Project
Backend
The main job of a service backend is to reliably manage the state of stacks. It provides dependencies to consumer stacks via the Stack Data Lookup pattern.
Name
URL
Authentication and Identity
The backend decides what a user can and cannot see, for example organizations, based on user's OD group configuration. A user's OD group list, as known by the Pulumi backend, is given by pulumi whoami --verbose
.
Service Backend
Secrets
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/secrets/
Logging
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/logging/
Assets and Archives
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/assets-archives/
Plugin
Plugin Operations
Function Serialization
TO PROCESS: https://www.pulumi.com/docs/intro/concepts/function-serialization/
Workspace
Modularization
TO PROCESS: https://www.pulumi.com/blog/creating-and-reusing-cloud-components-using-package-managers/
Packages
Pulumi Registry
CLI
Pulumi vs Terraform
Also see: