To keep track of what’s already created and what’s missing in your infrastructure, Pulumi uses a state file. Every time you execute Pulumi, it’ll read the code to determine what needs to be created or changed. Then it will compare that information with the state file. If there are no differences, it will assume that your infrastructure is already in the desired state.
For example, let’s say you write a Pulumi code to create a database, and there won’t be any metadata about any database in the state. In that case, Pulumi will create it and update the state file accordingly. That’s how Pulumi is not only recreating your whole infrastructure every time you run it but is also able to determine exactly what’s missing.
Pulumi stores the state file in a backend. Essentially, a backend is a storage endpoint for Pulumi to know where to save the state file. There are two classes of backends in Pulumi: service backend and self-managed backend.
Service is a cloud-based managed Pulumi backend available by default at app.pulumi.com. It promises a safe and easy-to-use way of storing your Pulumi state. It also offers many state-specific features, including:
- State encryption in transit and at rest
- Role-based access control for your team
- Auditing and rollback capabilities thanks to the full history of deployments
- State locking that prevents running two (or more) instances of Pulumi at the same time
Pulumi uses the Service backend by default. This means if you don’t specify otherwise and just execute pulumi login, you’ll log into the Pulumi Service backend available at app.pulumi.com.
You can also host Pulumi Service yourself. In that case, you’d log in to the Pulumi Service backend by providing a URL:
pulumi login https://service.example.com
Another type of state management in Pulumi is to not use a cloud-based service and self-manage the backend instead. If you choose this option, you can either keep the state locally or use cloud storage as a backend. Most cloud providers have support, so you can store your state in AWS S3, Azure Blob Storage, or Google Cloud Storage.
To keep the state locally, you need to log in to Pulumi with the –local parameter, like this:
pulumi login --local
To use cloud storage, you can execute one of these commands:
pulumi login s3://<bucket_name>
pulumi login azblob://<container_path>
#Google Cloud Storage
pulumi login gs://<bucket_name>
Sometimes you’ll have to create resources manually. This can create a problem. If you do it manually, then Pulumi won’t have an entry about the resource in its state file. Therefore, if you try to run Pulumi, it may delete or overwrite your resource.
Pulumi import lets you fix that.
You can tell Pulumi to update its state file with already existing resources. This is useful not only when you’re creating single resources manually but in other instances too.
For example, let’s say you decide to onboard a new team or project with already existing infrastructure. How can you do that? Execute pulumi import, and pass the resource type with its name and under which name you want Pulumi to save it. For instance:
pulumi import gcp:gs/bucket:Bucket backups infra-backups-bucket
Pulumi will then import the resource. That means it’ll add metadata about it to the state file, and it will create Pulumi code for you.
Why Does State Management Matter?
Pulumi state management is extremely important. Your state file defines your infrastructure and its primary source of truth for Pulumi. Any operations Pulumi will try to do (such as creating and changing resources) are based on the differences between the state file and the actual state of the infrastructure. Therefore, you should keep your state file safe in one of the supported backends or use Pulumi’s own managed Service backend.