github.com/alexissmirnov/terraform@v0.4.3-0.20150423153700-1ef9731a2f14/builtin/providers/aws/config.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/hashicorp/terraform/helper/multierror" 9 10 "github.com/awslabs/aws-sdk-go/aws" 11 "github.com/awslabs/aws-sdk-go/service/autoscaling" 12 "github.com/awslabs/aws-sdk-go/service/ec2" 13 "github.com/awslabs/aws-sdk-go/service/elb" 14 "github.com/awslabs/aws-sdk-go/service/iam" 15 "github.com/awslabs/aws-sdk-go/service/rds" 16 "github.com/awslabs/aws-sdk-go/service/route53" 17 "github.com/awslabs/aws-sdk-go/service/s3" 18 ) 19 20 type Config struct { 21 AccessKey string 22 SecretKey string 23 Token string 24 Region string 25 26 AllowedAccountIds []interface{} 27 ForbiddenAccountIds []interface{} 28 } 29 30 type AWSClient struct { 31 ec2conn *ec2.EC2 32 elbconn *elb.ELB 33 autoscalingconn *autoscaling.AutoScaling 34 s3conn *s3.S3 35 r53conn *route53.Route53 36 region string 37 rdsconn *rds.RDS 38 iamconn *iam.IAM 39 } 40 41 // Client configures and returns a fully initailized AWSClient 42 func (c *Config) Client() (interface{}, error) { 43 var client AWSClient 44 45 // Get the auth and region. This can fail if keys/regions were not 46 // specified and we're attempting to use the environment. 47 var errs []error 48 49 log.Println("[INFO] Building AWS region structure") 50 err := c.ValidateRegion() 51 if err != nil { 52 errs = append(errs, err) 53 } 54 55 if len(errs) == 0 { 56 // store AWS region in client struct, for region specific operations such as 57 // bucket storage in S3 58 client.region = c.Region 59 60 log.Println("[INFO] Building AWS auth structure") 61 creds := aws.DetectCreds(c.AccessKey, c.SecretKey, c.Token) 62 awsConfig := &aws.Config{ 63 Credentials: creds, 64 Region: c.Region, 65 } 66 67 log.Println("[INFO] Initializing ELB connection") 68 client.elbconn = elb.New(awsConfig) 69 70 log.Println("[INFO] Initializing S3 connection") 71 client.s3conn = s3.New(awsConfig) 72 73 log.Println("[INFO] Initializing RDS Connection") 74 client.rdsconn = rds.New(awsConfig) 75 76 log.Println("[INFO] Initializing IAM Connection") 77 client.iamconn = iam.New(awsConfig) 78 79 err := c.ValidateAccountId(client.iamconn) 80 if err != nil { 81 errs = append(errs, err) 82 } 83 84 log.Println("[INFO] Initializing AutoScaling connection") 85 client.autoscalingconn = autoscaling.New(awsConfig) 86 87 log.Println("[INFO] Initializing EC2 Connection") 88 client.ec2conn = ec2.New(awsConfig) 89 90 // aws-sdk-go uses v4 for signing requests, which requires all global 91 // endpoints to use 'us-east-1'. 92 // See http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html 93 log.Println("[INFO] Initializing Route 53 connection") 94 client.r53conn = route53.New(&aws.Config{ 95 Credentials: creds, 96 Region: "us-east-1", 97 }) 98 99 } 100 101 if len(errs) > 0 { 102 return nil, &multierror.Error{Errors: errs} 103 } 104 105 return &client, nil 106 } 107 108 // IsValidRegion returns true if the configured region is a valid AWS 109 // region and false if it's not 110 func (c *Config) ValidateRegion() error { 111 var regions = [11]string{"us-east-1", "us-west-2", "us-west-1", "eu-west-1", 112 "eu-central-1", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", 113 "sa-east-1", "cn-north-1", "us-gov-west-1"} 114 115 for _, valid := range regions { 116 if c.Region == valid { 117 return nil 118 } 119 } 120 return fmt.Errorf("Not a valid region: %s", c.Region) 121 } 122 123 func (c *Config) ValidateAccountId(iamconn *iam.IAM) error { 124 if c.AllowedAccountIds == nil && c.ForbiddenAccountIds == nil { 125 return nil 126 } 127 128 log.Printf("[INFO] Validating account ID") 129 130 out, err := iamconn.GetUser(nil) 131 if err != nil { 132 return fmt.Errorf("Failed getting account ID from IAM: %s", err) 133 } 134 135 account_id := strings.Split(*out.User.ARN, ":")[4] 136 137 if c.ForbiddenAccountIds != nil { 138 for _, id := range c.ForbiddenAccountIds { 139 if id == account_id { 140 return fmt.Errorf("Forbidden account ID (%s)", id) 141 } 142 } 143 } 144 145 if c.AllowedAccountIds != nil { 146 for _, id := range c.AllowedAccountIds { 147 if id == account_id { 148 return nil 149 } 150 } 151 return fmt.Errorf("Account ID not allowed (%s)", account_id) 152 } 153 154 return nil 155 }