Caching for Docker-based workers»
Docker-based workers cache tool binaries automatically on each host. See Caching for an explanation of tool and provider caches, storage requirements and cache limitations.
This page explains how to share the Terraform/OpenTofu provider cache between workers.
Configure the provider cache»
The configuration has two parts:
- A directory on shared storage, mounted on every worker instance and bind-mounted into run containers with
SPACELIFT_WORKER_EXTRA_MOUNTS. TF_PLUGIN_CACHE_DIRset inside the run container, pointing at the mount.
The storage must meet the shared storage requirements. On AWS, you can use Amazon FSx for OpenZFS or run an NFS server backed by an EBS volume.
Example: NFS server backed by EBS»
This example uses one dedicated EC2 instance as the NFS server. A gp3 EBS volume is attached to that instance and mounted at /srv/spacelift-provider-cache. Worker instances mount the exported directory over NFS.
The EBS volume is attached only to the NFS server. The workers do not attach the volume, and EBS Multi-Attach is not used.
Plan for NFS server resilience
This example is a starting point and does not configure high availability or failover for the NFS server. If the server is unavailable, the NFS hard mount option causes runs that access the cache to block until the server returns.
For production use, design the NFS server for the level of resilience your organization requires. The EBS volume must remain in its availability zone, and replacement servers need the same network endpoint or require workers to remount the export. How to implement that resilience is outside the scope of this guide.
If you do not want to manage this recovery process, consider using Kubernetes workers. The Kubernetes caching guide shows how to run the NFS server as a StatefulSet so that Kubernetes can reschedule it and reattach the EBS volume.
Configure the NFS server»
The following Terraform creates a dedicated NFS server, an encrypted gp3 EBS volume and a security group that allows NFS traffic from the workers. The NFS setup runs through the server's cloud-init user data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
The filesystem is formatted only when the volume is empty, so replacing the NFS server does not erase an existing cache. Run containers execute as UID 1983, which owns the cache directory. Mode 0750 prevents other users on the NFS server from reading or writing it.
The example limits NFS access to the worker security groups and subnet CIDR, and uses root_squash to prevent client root users from acting as root on the export. See Cache security before sharing a cache between stacks with different trust levels.
Configure the workers»
The steps below assume that you deployed the pool with the terraform-aws-spacelift-workerpool-on-ec2 module and the Spacelift worker AMI. The AMI uses Amazon Linux 2023 minimal, which does not include an NFS client.
Mount the export during instance startup and expose it to run containers. The module adds its configuration variable to each worker's cloud-init user data before the launcher starts. The launcher inherits any variables exported there:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
SPACELIFT_WORKER_EXTRA_MOUNTSbind-mounts the host directory into every run container at/mnt/provider-cache.SPACELIFT_WHITELIST_ENVSpassesTF_PLUGIN_CACHE_DIRfrom the launcher's environment into every run. This enables the cache for all stacks on the pool. To enable it only for selected stacks, remove the last twoexportlines and setTF_PLUGIN_CACHE_DIR=/mnt/provider-cacheon those stacks instead.
If you set TF_PLUGIN_CACHE_MAY_BREAK_DEPENDENCY_LOCK_FILE=true as described in Dependency lock files, also add it to SPACELIFT_WHITELIST_ENVS.
If you use the CloudFormation template, put the same commands in the secret referenced by CustomUserDataSecretName. See Injecting custom commands during instance startup.
Verify the cache»
After a run completes, the mount on each worker instance contains a directory for each registry, such as registry.opentofu.org/hashicorp/aws/6.0.0/linux_amd64/. On later runs, init reports that it is using providers from the cache instead of downloading them.