replace lock_table with dynamodb_table in s3 cfg

Since the DynamoDB table used by the S3 backend is no longer only used
for locks, rename it in the config to remove any confusion about it
being lock-specific.
This commit is contained in:
James Bardin 2017-05-25 19:12:20 -04:00
parent ecc5bfb801
commit 6b700ff1fb
5 changed files with 65 additions and 52 deletions

View File

@ -81,6 +81,14 @@ func New() backend.Backend {
Optional: true, Optional: true,
Description: "DynamoDB table for state locking", Description: "DynamoDB table for state locking",
Default: "", Default: "",
Deprecated: "please use the dynamodb_table attribute",
},
"dynamodb_table": {
Type: schema.TypeString,
Optional: true,
Description: "DynamoDB table for state locking and consistency",
Default: "",
}, },
"profile": { "profile": {
@ -151,7 +159,7 @@ type Backend struct {
serverSideEncryption bool serverSideEncryption bool
acl string acl string
kmsKeyID string kmsKeyID string
lockTable string ddbTable string
} }
func (b *Backend) configure(ctx context.Context) error { func (b *Backend) configure(ctx context.Context) error {
@ -167,7 +175,12 @@ func (b *Backend) configure(ctx context.Context) error {
b.serverSideEncryption = data.Get("encrypt").(bool) b.serverSideEncryption = data.Get("encrypt").(bool)
b.acl = data.Get("acl").(string) b.acl = data.Get("acl").(string)
b.kmsKeyID = data.Get("kms_key_id").(string) b.kmsKeyID = data.Get("kms_key_id").(string)
b.lockTable = data.Get("lock_table").(string)
b.ddbTable = data.Get("dynamodb_table").(string)
if b.ddbTable == "" {
// try the depracted field
b.ddbTable = data.Get("lock_table").(string)
}
cfg := &terraformAWS.Config{ cfg := &terraformAWS.Config{
AccessKey: data.Get("access_key").(string), AccessKey: data.Get("access_key").(string),

View File

@ -96,7 +96,7 @@ func (b *Backend) State(name string) (state.State, error) {
serverSideEncryption: b.serverSideEncryption, serverSideEncryption: b.serverSideEncryption,
acl: b.acl, acl: b.acl,
kmsKeyID: b.kmsKeyID, kmsKeyID: b.kmsKeyID,
lockTable: b.lockTable, ddbTable: b.ddbTable,
} }
stateMgr := &remote.State{Client: client} stateMgr := &remote.State{Client: client}

View File

@ -34,11 +34,11 @@ func TestBackend_impl(t *testing.T) {
func TestBackendConfig(t *testing.T) { func TestBackendConfig(t *testing.T) {
testACC(t) testACC(t)
config := map[string]interface{}{ config := map[string]interface{}{
"region": "us-west-1", "region": "us-west-1",
"bucket": "tf-test", "bucket": "tf-test",
"key": "state", "key": "state",
"encrypt": true, "encrypt": true,
"lock_table": "dynamoTable", "dynamodb_table": "dynamoTable",
} }
b := backend.TestBackendConfig(t, New(), config).(*Backend) b := backend.TestBackendConfig(t, New(), config).(*Backend)
@ -90,17 +90,17 @@ func TestBackendLocked(t *testing.T) {
keyName := "test/state" keyName := "test/state"
b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"encrypt": true, "encrypt": true,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"encrypt": true, "encrypt": true,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
createS3Bucket(t, b1.s3Client, bucketName) createS3Bucket(t, b1.s3Client, bucketName)
@ -139,7 +139,7 @@ func TestBackendExtraPaths(t *testing.T) {
serverSideEncryption: b.serverSideEncryption, serverSideEncryption: b.serverSideEncryption,
acl: b.acl, acl: b.acl,
kmsKeyID: b.kmsKeyID, kmsKeyID: b.kmsKeyID,
lockTable: b.lockTable, ddbTable: b.ddbTable,
} }
stateMgr := &remote.State{Client: client} stateMgr := &remote.State{Client: client}

View File

@ -32,7 +32,7 @@ type RemoteClient struct {
serverSideEncryption bool serverSideEncryption bool
acl string acl string
kmsKeyID string kmsKeyID string
lockTable string ddbTable string
} }
var ( var (
@ -191,7 +191,7 @@ func (c *RemoteClient) Delete() error {
} }
func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) { func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) {
if c.lockTable == "" { if c.ddbTable == "" {
return "", nil return "", nil
} }
@ -211,7 +211,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) {
"LockID": {S: aws.String(c.lockPath())}, "LockID": {S: aws.String(c.lockPath())},
"Info": {S: aws.String(string(info.Marshal()))}, "Info": {S: aws.String(string(info.Marshal()))},
}, },
TableName: aws.String(c.lockTable), TableName: aws.String(c.ddbTable),
ConditionExpression: aws.String("attribute_not_exists(LockID)"), ConditionExpression: aws.String("attribute_not_exists(LockID)"),
} }
_, err := c.dynClient.PutItem(putParams) _, err := c.dynClient.PutItem(putParams)
@ -233,7 +233,7 @@ func (c *RemoteClient) Lock(info *state.LockInfo) (string, error) {
} }
func (c *RemoteClient) getMD5() ([]byte, error) { func (c *RemoteClient) getMD5() ([]byte, error) {
if c.lockTable == "" { if c.ddbTable == "" {
return nil, nil return nil, nil
} }
@ -242,7 +242,7 @@ func (c *RemoteClient) getMD5() ([]byte, error) {
"LockID": {S: aws.String(c.lockPath() + stateIDSuffix)}, "LockID": {S: aws.String(c.lockPath() + stateIDSuffix)},
}, },
ProjectionExpression: aws.String("LockID, Digest"), ProjectionExpression: aws.String("LockID, Digest"),
TableName: aws.String(c.lockTable), TableName: aws.String(c.ddbTable),
} }
resp, err := c.dynClient.GetItem(getParams) resp, err := c.dynClient.GetItem(getParams)
@ -265,7 +265,7 @@ func (c *RemoteClient) getMD5() ([]byte, error) {
// store the hash of the state to that clients can check for stale state files. // store the hash of the state to that clients can check for stale state files.
func (c *RemoteClient) putMD5(sum []byte) error { func (c *RemoteClient) putMD5(sum []byte) error {
if c.lockTable == "" { if c.ddbTable == "" {
return nil return nil
} }
@ -278,7 +278,7 @@ func (c *RemoteClient) putMD5(sum []byte) error {
"LockID": {S: aws.String(c.lockPath() + stateIDSuffix)}, "LockID": {S: aws.String(c.lockPath() + stateIDSuffix)},
"Digest": {S: aws.String(hex.EncodeToString(sum))}, "Digest": {S: aws.String(hex.EncodeToString(sum))},
}, },
TableName: aws.String(c.lockTable), TableName: aws.String(c.ddbTable),
} }
_, err := c.dynClient.PutItem(putParams) _, err := c.dynClient.PutItem(putParams)
if err != nil { if err != nil {
@ -290,7 +290,7 @@ func (c *RemoteClient) putMD5(sum []byte) error {
// remove the hash value for a deleted state // remove the hash value for a deleted state
func (c *RemoteClient) deleteMD5() error { func (c *RemoteClient) deleteMD5() error {
if c.lockTable == "" { if c.ddbTable == "" {
return nil return nil
} }
@ -298,7 +298,7 @@ func (c *RemoteClient) deleteMD5() error {
Key: map[string]*dynamodb.AttributeValue{ Key: map[string]*dynamodb.AttributeValue{
"LockID": {S: aws.String(c.lockPath() + stateIDSuffix)}, "LockID": {S: aws.String(c.lockPath() + stateIDSuffix)},
}, },
TableName: aws.String(c.lockTable), TableName: aws.String(c.ddbTable),
} }
if _, err := c.dynClient.DeleteItem(params); err != nil { if _, err := c.dynClient.DeleteItem(params); err != nil {
return err return err
@ -312,7 +312,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) {
"LockID": {S: aws.String(c.lockPath())}, "LockID": {S: aws.String(c.lockPath())},
}, },
ProjectionExpression: aws.String("LockID, Info"), ProjectionExpression: aws.String("LockID, Info"),
TableName: aws.String(c.lockTable), TableName: aws.String(c.ddbTable),
} }
resp, err := c.dynClient.GetItem(getParams) resp, err := c.dynClient.GetItem(getParams)
@ -335,7 +335,7 @@ func (c *RemoteClient) getLockInfo() (*state.LockInfo, error) {
} }
func (c *RemoteClient) Unlock(id string) error { func (c *RemoteClient) Unlock(id string) error {
if c.lockTable == "" { if c.ddbTable == "" {
return nil return nil
} }
@ -360,7 +360,7 @@ func (c *RemoteClient) Unlock(id string) error {
Key: map[string]*dynamodb.AttributeValue{ Key: map[string]*dynamodb.AttributeValue{
"LockID": {S: aws.String(c.lockPath())}, "LockID": {S: aws.String(c.lockPath())},
}, },
TableName: aws.String(c.lockTable), TableName: aws.String(c.ddbTable),
} }
_, err = c.dynClient.DeleteItem(params) _, err = c.dynClient.DeleteItem(params)

View File

@ -47,17 +47,17 @@ func TestRemoteClientLocks(t *testing.T) {
keyName := "testState" keyName := "testState"
b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"encrypt": true, "encrypt": true,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"encrypt": true, "encrypt": true,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
createS3Bucket(t, b1.s3Client, bucketName) createS3Bucket(t, b1.s3Client, bucketName)
@ -85,17 +85,17 @@ func TestForceUnlock(t *testing.T) {
keyName := "testState" keyName := "testState"
b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"encrypt": true, "encrypt": true,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"encrypt": true, "encrypt": true,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
createS3Bucket(t, b1.s3Client, bucketName) createS3Bucket(t, b1.s3Client, bucketName)
@ -162,9 +162,9 @@ func TestRemoteClient_clientMD5(t *testing.T) {
keyName := "testState" keyName := "testState"
b := backend.TestBackendConfig(t, New(), map[string]interface{}{ b := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
createS3Bucket(t, b.s3Client, bucketName) createS3Bucket(t, b.s3Client, bucketName)
@ -210,9 +210,9 @@ func TestRemoteClient_stateChecksum(t *testing.T) {
keyName := "testState" keyName := "testState"
b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b1 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,
"key": keyName, "key": keyName,
"lock_table": bucketName, "dynamodb_table": bucketName,
}).(*Backend) }).(*Backend)
createS3Bucket(t, b1.s3Client, bucketName) createS3Bucket(t, b1.s3Client, bucketName)
@ -238,7 +238,7 @@ func TestRemoteClient_stateChecksum(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Use b2 without a lock_table to bypass the lock table to write the state directly. // Use b2 without a dynamodb_table to bypass the lock table to write the state directly.
// client2 will write the "incorrect" state, simulating s3 eventually consistency delays // client2 will write the "incorrect" state, simulating s3 eventually consistency delays
b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{ b2 := backend.TestBackendConfig(t, New(), map[string]interface{}{
"bucket": bucketName, "bucket": bucketName,