Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce S3-native state locking #35661

Merged
merged 18 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions internal/backend/remote-state/s3/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Backend struct {
acl string
kmsKeyID string
ddbTable string
useLockFile bool
workspaceKeyPrefix string
skipS3Checksum bool
}
Expand Down Expand Up @@ -152,6 +153,11 @@ func (b *Backend) ConfigSchema() *configschema.Block {
Optional: true,
Description: "DynamoDB table for state locking and consistency",
},
"use_lockfile": {
Type: cty.Bool,
Optional: true,
Description: "(Experimental) Whether to use a lockfile for locking the state file.",
},
"profile": {
Type: cty.String,
Optional: true,
Expand Down Expand Up @@ -822,6 +828,7 @@ func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics {
b.serverSideEncryption = boolAttr(obj, "encrypt")
b.kmsKeyID = stringAttr(obj, "kms_key_id")
b.ddbTable = stringAttr(obj, "dynamodb_table")
b.useLockFile = boolAttr(obj, "use_lockfile")
b.skipS3Checksum = boolAttr(obj, "skip_s3_checksum")

if _, ok := stringAttrOk(obj, "kms_key_id"); ok {
Expand Down
10 changes: 10 additions & 0 deletions internal/backend/remote-state/s3/backend_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const (
// defaultWorkspaceKeyPrefix is the default prefix for workspace storage.
// The colon is used to reduce the chance of name conflicts with existing objects.
defaultWorkspaceKeyPrefix = "env:"
// lockFileSuffix defines the suffix for Terraform state lock files.
lockFileSuffix = ".tflock"
)

func (b *Backend) Workspaces() ([]string, error) {
Expand Down Expand Up @@ -163,6 +165,8 @@ func (b *Backend) remoteClient(name string) (*RemoteClient, error) {
kmsKeyID: b.kmsKeyID,
ddbTable: b.ddbTable,
skipS3Checksum: b.skipS3Checksum,
lockFilePath: b.getLockFilePath(name),
useLockFile: b.useLockFile,
}

return client, nil
Expand Down Expand Up @@ -276,3 +280,9 @@ func newBucketRegionError(requestRegion, bucketRegion string) bucketRegionError
func (err bucketRegionError) Error() string {
return fmt.Sprintf("requested bucket from %q, actual location %q", err.requestRegion, err.bucketRegion)
}

// getLockFilePath returns the path to the lock file for the given Terraform state.
// For `default.tfstate`, the lock file is stored at `default.tfstate.tflock`.
func (b *Backend) getLockFilePath(name string) string {
return b.path(name) + lockFileSuffix
}
Loading
Loading