Allow s3 backends to contain more then 1000 workspaces

* backend/remote-state/s3/backend_state.go: Prior to this commit, the terraform s3 backend did
  not paginate calls to s3 when finding workspaces, which resulted in workspaces 'disappearing'
  once they are switched away from, even though the state file still exists. This is due to the
  ListBucket operation defaulting MaxItems to 1000, so terraform s3 backends that contained
  more then 1000 workspaces did not function as expected. This rectifies this situation by
  paginating calls to s3 when finding workspaces.

Signed-off-by: Collin J. Doering <collin@rekahsoft.ca>
This commit is contained in:
Collin J. Doering 2019-10-01 11:46:34 -04:00
parent 6f313abc9e
commit 6d838ed76c
No known key found for this signature in database
GPG Key ID: 7B4DEB93212B3022
1 changed files with 16 additions and 14 deletions

View File

@ -18,6 +18,8 @@ import (
)
func (b *Backend) Workspaces() ([]string, error) {
const maxKeys = 1000
prefix := ""
if b.workspaceKeyPrefix != "" {
@ -25,24 +27,24 @@ func (b *Backend) Workspaces() ([]string, error) {
}
params := &s3.ListObjectsInput{
Bucket: &b.bucketName,
Prefix: aws.String(prefix),
}
resp, err := b.s3Client.ListObjects(params)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == s3.ErrCodeNoSuchBucket {
return nil, fmt.Errorf(errS3NoSuchBucket, err)
}
return nil, err
Bucket: &b.bucketName,
Prefix: aws.String(prefix),
MaxKeys: aws.Int64(maxKeys),
}
wss := []string{backend.DefaultStateName}
for _, obj := range resp.Contents {
ws := b.keyEnv(*obj.Key)
if ws != "" {
wss = append(wss, ws)
err := b.s3Client.ListObjectsPages(params, func(page *s3.ListObjectsOutput, lastPage bool) bool {
for _, obj := range page.Contents {
ws := b.keyEnv(*obj.Key)
if ws != "" {
wss = append(wss, ws)
}
}
return !lastPage
})
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == s3.ErrCodeNoSuchBucket {
return nil, fmt.Errorf(errS3NoSuchBucket, err)
}
sort.Strings(wss[1:])