github.com/lymingtonprecision/terraform@v0.9.9-0.20170613092852-62acef9611a9/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  	}
   144  
   145  	result := &Backend{Backend: s}
   146  	result.Backend.ConfigureFunc = result.configure
   147  	return result
   148  }
   149  
   150  type Backend struct {
   151  	*schema.Backend
   152  
   153  	// The fields below are set from configure
   154  	s3Client  *s3.S3
   155  	dynClient *dynamodb.DynamoDB
   156  
   157  	bucketName           string
   158  	keyName              string
   159  	serverSideEncryption bool
   160  	acl                  string
   161  	kmsKeyID             string
   162  	ddbTable             string
   163  }
   164  
   165  func (b *Backend) configure(ctx context.Context) error {
   166  	if b.s3Client != nil {
   167  		return nil
   168  	}
   169  
   170  	// Grab the resource data
   171  	data := schema.FromContextBackendConfig(ctx)
   172  
   173  	b.bucketName = data.Get("bucket").(string)
   174  	b.keyName = data.Get("key").(string)
   175  	b.serverSideEncryption = data.Get("encrypt").(bool)
   176  	b.acl = data.Get("acl").(string)
   177  	b.kmsKeyID = data.Get("kms_key_id").(string)
   178  
   179  	b.ddbTable = data.Get("dynamodb_table").(string)
   180  	if b.ddbTable == "" {
   181  		// try the depracted field
   182  		b.ddbTable = data.Get("lock_table").(string)
   183  	}
   184  
   185  	cfg := &terraformAWS.Config{
   186  		AccessKey:             data.Get("access_key").(string),
   187  		AssumeRoleARN:         data.Get("role_arn").(string),
   188  		AssumeRoleExternalID:  data.Get("external_id").(string),
   189  		AssumeRolePolicy:      data.Get("assume_role_policy").(string),
   190  		AssumeRoleSessionName: data.Get("session_name").(string),
   191  		CredsFilename:         data.Get("shared_credentials_file").(string),
   192  		Profile:               data.Get("profile").(string),
   193  		Region:                data.Get("region").(string),
   194  		S3Endpoint:            data.Get("endpoint").(string),
   195  		SecretKey:             data.Get("secret_key").(string),
   196  		Token:                 data.Get("token").(string),
   197  	}
   198  
   199  	client, err := cfg.Client()
   200  	if err != nil {
   201  		return err
   202  	}
   203  
   204  	b.s3Client = client.(*terraformAWS.AWSClient).S3()
   205  	b.dynClient = client.(*terraformAWS.AWSClient).DynamoDB()
   206  
   207  	return nil
   208  }