github.com/ticketmaster/terraform@v0.10.0-beta2.0.20170711045249-a12daf5aba4f/backend/remote-state/s3/backend.go (about) 1 package s3 2 3 import ( 4 "context" 5 6 "github.com/aws/aws-sdk-go/service/dynamodb" 7 "github.com/aws/aws-sdk-go/service/s3" 8 "github.com/hashicorp/terraform/backend" 9 "github.com/hashicorp/terraform/helper/schema" 10 11 terraformAWS "github.com/terraform-providers/terraform-provider-aws/aws" 12 ) 13 14 // New creates a new backend for S3 remote state. 15 func New() backend.Backend { 16 s := &schema.Backend{ 17 Schema: map[string]*schema.Schema{ 18 "bucket": { 19 Type: schema.TypeString, 20 Required: true, 21 Description: "The name of the S3 bucket", 22 }, 23 24 "key": { 25 Type: schema.TypeString, 26 Required: true, 27 Description: "The path to the state file inside the bucket", 28 }, 29 30 "region": { 31 Type: schema.TypeString, 32 Required: true, 33 Description: "The region of the S3 bucket.", 34 DefaultFunc: schema.EnvDefaultFunc("AWS_DEFAULT_REGION", nil), 35 }, 36 37 "endpoint": { 38 Type: schema.TypeString, 39 Optional: true, 40 Description: "A custom endpoint for the S3 API", 41 DefaultFunc: schema.EnvDefaultFunc("AWS_S3_ENDPOINT", ""), 42 }, 43 44 "encrypt": { 45 Type: schema.TypeBool, 46 Optional: true, 47 Description: "Whether to enable server side encryption of the state file", 48 Default: false, 49 }, 50 51 "acl": { 52 Type: schema.TypeString, 53 Optional: true, 54 Description: "Canned ACL to be applied to the state file", 55 Default: "", 56 }, 57 58 "access_key": { 59 Type: schema.TypeString, 60 Optional: true, 61 Description: "AWS access key", 62 Default: "", 63 }, 64 65 "secret_key": { 66 Type: schema.TypeString, 67 Optional: true, 68 Description: "AWS secret key", 69 Default: "", 70 }, 71 72 "kms_key_id": { 73 Type: schema.TypeString, 74 Optional: true, 75 Description: "The ARN of a KMS Key to use for encrypting the state", 76 Default: "", 77 }, 78 79 "lock_table": { 80 Type: schema.TypeString, 81 Optional: true, 82 Description: "DynamoDB table for state locking", 83 Default: "", 84 Deprecated: "please use the dynamodb_table attribute", 85 }, 86 87 "dynamodb_table": { 88 Type: schema.TypeString, 89 Optional: true, 90 Description: "DynamoDB table for state locking and consistency", 91 Default: "", 92 }, 93 94 "profile": { 95 Type: schema.TypeString, 96 Optional: true, 97 Description: "AWS profile name", 98 Default: "", 99 }, 100 101 "shared_credentials_file": { 102 Type: schema.TypeString, 103 Optional: true, 104 Description: "Path to a shared credentials file", 105 Default: "", 106 }, 107 108 "token": { 109 Type: schema.TypeString, 110 Optional: true, 111 Description: "MFA token", 112 Default: "", 113 }, 114 115 "role_arn": { 116 Type: schema.TypeString, 117 Optional: true, 118 Description: "The role to be assumed", 119 Default: "", 120 }, 121 122 "session_name": { 123 Type: schema.TypeString, 124 Optional: true, 125 Description: "The session name to use when assuming the role.", 126 Default: "", 127 }, 128 129 "external_id": { 130 Type: schema.TypeString, 131 Optional: true, 132 Description: "The external ID to use when assuming the role", 133 Default: "", 134 }, 135 136 "assume_role_policy": { 137 Type: schema.TypeString, 138 Optional: true, 139 Description: "The permissions applied when assuming a role.", 140 Default: "", 141 }, 142 143 "workspace_key_prefix": { 144 Type: schema.TypeString, 145 Optional: true, 146 Description: "The prefix applied to the non-default state path inside the bucket", 147 Default: "env:", 148 }, 149 }, 150 } 151 152 result := &Backend{Backend: s} 153 result.Backend.ConfigureFunc = result.configure 154 return result 155 } 156 157 type Backend struct { 158 *schema.Backend 159 160 // The fields below are set from configure 161 s3Client *s3.S3 162 dynClient *dynamodb.DynamoDB 163 164 bucketName string 165 keyName string 166 serverSideEncryption bool 167 acl string 168 kmsKeyID string 169 ddbTable string 170 workspaceKeyPrefix string 171 } 172 173 func (b *Backend) configure(ctx context.Context) error { 174 if b.s3Client != nil { 175 return nil 176 } 177 178 // Grab the resource data 179 data := schema.FromContextBackendConfig(ctx) 180 181 b.bucketName = data.Get("bucket").(string) 182 b.keyName = data.Get("key").(string) 183 b.serverSideEncryption = data.Get("encrypt").(bool) 184 b.acl = data.Get("acl").(string) 185 b.kmsKeyID = data.Get("kms_key_id").(string) 186 b.workspaceKeyPrefix = data.Get("workspace_key_prefix").(string) 187 188 b.ddbTable = data.Get("dynamodb_table").(string) 189 if b.ddbTable == "" { 190 // try the depracted field 191 b.ddbTable = data.Get("lock_table").(string) 192 } 193 194 cfg := &terraformAWS.Config{ 195 AccessKey: data.Get("access_key").(string), 196 AssumeRoleARN: data.Get("role_arn").(string), 197 AssumeRoleExternalID: data.Get("external_id").(string), 198 AssumeRolePolicy: data.Get("assume_role_policy").(string), 199 AssumeRoleSessionName: data.Get("session_name").(string), 200 CredsFilename: data.Get("shared_credentials_file").(string), 201 Profile: data.Get("profile").(string), 202 Region: data.Get("region").(string), 203 S3Endpoint: data.Get("endpoint").(string), 204 SecretKey: data.Get("secret_key").(string), 205 Token: data.Get("token").(string), 206 } 207 208 client, err := cfg.Client() 209 if err != nil { 210 return err 211 } 212 213 b.s3Client = client.(*terraformAWS.AWSClient).S3() 214 b.dynClient = client.(*terraformAWS.AWSClient).DynamoDB() 215 216 return nil 217 }