github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/builtin/providers/aws/config.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "unicode" 8 9 "github.com/hashicorp/terraform/helper/multierror" 10 "github.com/mitchellh/goamz/aws" 11 "github.com/mitchellh/goamz/ec2" 12 "github.com/mitchellh/goamz/elb" 13 "github.com/mitchellh/goamz/rds" 14 15 awsGo "github.com/awslabs/aws-sdk-go/aws" 16 "github.com/awslabs/aws-sdk-go/gen/autoscaling" 17 "github.com/awslabs/aws-sdk-go/gen/route53" 18 "github.com/awslabs/aws-sdk-go/gen/s3" 19 ) 20 21 type Config struct { 22 AccessKey string 23 SecretKey string 24 Region string 25 } 26 27 type AWSClient struct { 28 ec2conn *ec2.EC2 29 elbconn *elb.ELB 30 autoscalingconn *autoscaling.AutoScaling 31 s3conn *s3.S3 32 rdsconn *rds.Rds 33 r53conn *route53.Route53 34 region string 35 } 36 37 // Client configures and returns a fully initailized AWSClient 38 func (c *Config) Client() (interface{}, error) { 39 var client AWSClient 40 41 // Get the auth and region. This can fail if keys/regions were not 42 // specified and we're attempting to use the environment. 43 var errs []error 44 log.Println("[INFO] Building AWS auth structure") 45 auth, err := c.AWSAuth() 46 if err != nil { 47 errs = append(errs, err) 48 } 49 50 log.Println("[INFO] Building AWS region structure") 51 region, err := c.AWSRegion() 52 if err != nil { 53 errs = append(errs, err) 54 } 55 56 if len(errs) == 0 { 57 // store AWS region in client struct, for region specific operations such as 58 // bucket storage in S3 59 client.region = c.Region 60 61 creds := awsGo.Creds(c.AccessKey, c.SecretKey, "") 62 63 log.Println("[INFO] Initializing EC2 connection") 64 client.ec2conn = ec2.New(auth, region) 65 log.Println("[INFO] Initializing ELB connection") 66 client.elbconn = elb.New(auth, region) 67 log.Println("[INFO] Initializing AutoScaling connection") 68 client.autoscalingconn = autoscaling.New(creds, c.Region, nil) 69 log.Println("[INFO] Initializing S3 connection") 70 client.s3conn = s3.New(creds, c.Region, nil) 71 log.Println("[INFO] Initializing RDS connection") 72 client.rdsconn = rds.New(auth, region) 73 74 // aws-sdk-go uses v4 for signing requests, which requires all global 75 // endpoints to use 'us-east-1'. 76 // See http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html 77 log.Println("[INFO] Initializing Route53 connection") 78 client.r53conn = route53.New(creds, "us-east-1", nil) 79 } 80 81 if len(errs) > 0 { 82 return nil, &multierror.Error{Errors: errs} 83 } 84 85 return &client, nil 86 } 87 88 // AWSAuth returns a valid aws.Auth object for access to AWS services, or 89 // an error if the authentication couldn't be resolved. 90 // 91 // TODO(mitchellh): Test in some way. 92 func (c *Config) AWSAuth() (aws.Auth, error) { 93 auth, err := aws.GetAuth(c.AccessKey, c.SecretKey) 94 if err == nil { 95 // Store the accesskey and secret that we got... 96 c.AccessKey = auth.AccessKey 97 c.SecretKey = auth.SecretKey 98 } 99 100 return auth, err 101 } 102 103 // IsValidRegion returns true if the configured region is a valid AWS 104 // region and false if it's not 105 func (c *Config) IsValidRegion() bool { 106 var regions = [11]string{"us-east-1", "us-west-2", "us-west-1", "eu-west-1", 107 "eu-central-1", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", 108 "sa-east-1", "cn-north-1", "us-gov-west-1"} 109 110 for _, valid := range regions { 111 if c.Region == valid { 112 return true 113 } 114 } 115 return false 116 } 117 118 // AWSRegion returns the configured region. 119 // 120 // TODO(mitchellh): Test in some way. 121 func (c *Config) AWSRegion() (aws.Region, error) { 122 if c.Region != "" { 123 if c.IsValidRegion() { 124 return aws.Regions[c.Region], nil 125 } else { 126 return aws.Region{}, fmt.Errorf("Not a valid region: %s", c.Region) 127 } 128 } 129 130 md, err := aws.GetMetaData("placement/availability-zone") 131 if err != nil { 132 return aws.Region{}, err 133 } 134 135 region := strings.TrimRightFunc(string(md), unicode.IsLetter) 136 return aws.Regions[region], nil 137 }