github.com/archgrove/terraform@v0.9.5-0.20170502093151-adb789f0f8d2/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/hashicorp/terraform/builtin/providers/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  			},
    85  
    86  			"profile": {
    87  				Type:        schema.TypeString,
    88  				Optional:    true,
    89  				Description: "AWS profile name",
    90  				Default:     "",
    91  			},
    92  
    93  			"shared_credentials_file": {
    94  				Type:        schema.TypeString,
    95  				Optional:    true,
    96  				Description: "Path to a shared credentials file",
    97  				Default:     "",
    98  			},
    99  
   100  			"token": {
   101  				Type:        schema.TypeString,
   102  				Optional:    true,
   103  				Description: "MFA token",
   104  				Default:     "",
   105  			},
   106  
   107  			"role_arn": {
   108  				Type:        schema.TypeString,
   109  				Optional:    true,
   110  				Description: "The role to be assumed",
   111  				Default:     "",
   112  			},
   113  
   114  			"session_name": {
   115  				Type:        schema.TypeString,
   116  				Optional:    true,
   117  				Description: "The session name to use when assuming the role.",
   118  				Default:     "",
   119  			},
   120  
   121  			"external_id": {
   122  				Type:        schema.TypeString,
   123  				Optional:    true,
   124  				Description: "The external ID to use when assuming the role",
   125  				Default:     "",
   126  			},
   127  
   128  			"assume_role_policy": {
   129  				Type:        schema.TypeString,
   130  				Optional:    true,
   131  				Description: "The permissions applied when assuming a role.",
   132  				Default:     "",
   133  			},
   134  		},
   135  	}
   136  
   137  	result := &Backend{Backend: s}
   138  	result.Backend.ConfigureFunc = result.configure
   139  	return result
   140  }
   141  
   142  type Backend struct {
   143  	*schema.Backend
   144  
   145  	// The fields below are set from configure
   146  	s3Client  *s3.S3
   147  	dynClient *dynamodb.DynamoDB
   148  
   149  	bucketName           string
   150  	keyName              string
   151  	serverSideEncryption bool
   152  	acl                  string
   153  	kmsKeyID             string
   154  	lockTable            string
   155  }
   156  
   157  func (b *Backend) configure(ctx context.Context) error {
   158  	if b.s3Client != nil {
   159  		return nil
   160  	}
   161  
   162  	// Grab the resource data
   163  	data := schema.FromContextBackendConfig(ctx)
   164  
   165  	b.bucketName = data.Get("bucket").(string)
   166  	b.keyName = data.Get("key").(string)
   167  	b.serverSideEncryption = data.Get("encrypt").(bool)
   168  	b.acl = data.Get("acl").(string)
   169  	b.kmsKeyID = data.Get("kms_key_id").(string)
   170  	b.lockTable = data.Get("lock_table").(string)
   171  
   172  	cfg := &terraformAWS.Config{
   173  		AccessKey:             data.Get("access_key").(string),
   174  		AssumeRoleARN:         data.Get("role_arn").(string),
   175  		AssumeRoleExternalID:  data.Get("external_id").(string),
   176  		AssumeRolePolicy:      data.Get("assume_role_policy").(string),
   177  		AssumeRoleSessionName: data.Get("session_name").(string),
   178  		CredsFilename:         data.Get("shared_credentials_file").(string),
   179  		Profile:               data.Get("profile").(string),
   180  		Region:                data.Get("region").(string),
   181  		S3Endpoint:            data.Get("endpoint").(string),
   182  		SecretKey:             data.Get("secret_key").(string),
   183  		Token:                 data.Get("token").(string),
   184  	}
   185  
   186  	client, err := cfg.Client()
   187  	if err != nil {
   188  		return err
   189  	}
   190  
   191  	b.s3Client = client.(*terraformAWS.AWSClient).S3()
   192  	b.dynClient = client.(*terraformAWS.AWSClient).DynamoDB()
   193  
   194  	return nil
   195  }