github.com/acm1/terraform@v0.6.2-0.20150729164239-1f314444f45c/builtin/providers/aws/provider.go (about)

     1  package aws
     2  
     3  import (
     4  	"net"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/awslabs/aws-sdk-go/aws/credentials"
     9  	"github.com/hashicorp/terraform/helper/hashcode"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  // Provider returns a terraform.ResourceProvider.
    15  func Provider() terraform.ResourceProvider {
    16  	// TODO: Move the validation to this, requires conditional schemas
    17  	// TODO: Move the configuration to this, requires validation
    18  
    19  	// These variables are closed within the `getCreds` function below.
    20  	// This function is responsible for reading credentials from the
    21  	// environment in the case that they're not explicitly specified
    22  	// in the Terraform configuration.
    23  	//
    24  	// By using the getCreds function here instead of making the default
    25  	// empty, we avoid asking for input on credentials if they're available
    26  	// in the environment.
    27  	var credVal credentials.Value
    28  	var credErr error
    29  	var once sync.Once
    30  	getCreds := func() {
    31  		// Build the list of providers to look for creds in
    32  		providers := []credentials.Provider{
    33  			&credentials.EnvProvider{},
    34  			&credentials.SharedCredentialsProvider{},
    35  		}
    36  
    37  		// We only look in the EC2 metadata API if we can connect
    38  		// to the metadata service within a reasonable amount of time
    39  		conn, err := net.DialTimeout("tcp", "169.254.169.254:80", 100*time.Millisecond)
    40  		if err == nil {
    41  			conn.Close()
    42  			providers = append(providers, &credentials.EC2RoleProvider{})
    43  		}
    44  
    45  		credVal, credErr = credentials.NewChainCredentials(providers).Get()
    46  
    47  		// If we didn't successfully find any credentials, just
    48  		// set the error to nil.
    49  		if credErr == credentials.ErrNoValidProvidersFoundInChain {
    50  			credErr = nil
    51  		}
    52  	}
    53  
    54  	// getCredDefault is a function used by DefaultFunc below to
    55  	// get the default value for various parts of the credentials.
    56  	// This function properly handles loading the credentials, checking
    57  	// for errors, etc.
    58  	getCredDefault := func(def interface{}, f func() string) (interface{}, error) {
    59  		once.Do(getCreds)
    60  
    61  		// If there was an error, that is always first
    62  		if credErr != nil {
    63  			return nil, credErr
    64  		}
    65  
    66  		// If the value is empty string, return nil (not set)
    67  		val := f()
    68  		if val == "" {
    69  			return def, nil
    70  		}
    71  
    72  		return val, nil
    73  	}
    74  
    75  	// The actual provider
    76  	return &schema.Provider{
    77  		Schema: map[string]*schema.Schema{
    78  			"access_key": &schema.Schema{
    79  				Type:     schema.TypeString,
    80  				Required: true,
    81  				DefaultFunc: func() (interface{}, error) {
    82  					return getCredDefault(nil, func() string {
    83  						return credVal.AccessKeyID
    84  					})
    85  				},
    86  				Description: descriptions["access_key"],
    87  			},
    88  
    89  			"secret_key": &schema.Schema{
    90  				Type:     schema.TypeString,
    91  				Required: true,
    92  				DefaultFunc: func() (interface{}, error) {
    93  					return getCredDefault(nil, func() string {
    94  						return credVal.SecretAccessKey
    95  					})
    96  				},
    97  				Description: descriptions["secret_key"],
    98  			},
    99  
   100  			"token": &schema.Schema{
   101  				Type:     schema.TypeString,
   102  				Optional: true,
   103  				DefaultFunc: func() (interface{}, error) {
   104  					return getCredDefault("", func() string {
   105  						return credVal.SessionToken
   106  					})
   107  				},
   108  				Description: descriptions["token"],
   109  			},
   110  
   111  			"region": &schema.Schema{
   112  				Type:     schema.TypeString,
   113  				Required: true,
   114  				DefaultFunc: schema.MultiEnvDefaultFunc([]string{
   115  					"AWS_REGION",
   116  					"AWS_DEFAULT_REGION",
   117  				}, nil),
   118  				Description:  descriptions["region"],
   119  				InputDefault: "us-east-1",
   120  			},
   121  
   122  			"max_retries": &schema.Schema{
   123  				Type:        schema.TypeInt,
   124  				Optional:    true,
   125  				Default:     11,
   126  				Description: descriptions["max_retries"],
   127  			},
   128  
   129  			"allowed_account_ids": &schema.Schema{
   130  				Type:          schema.TypeSet,
   131  				Elem:          &schema.Schema{Type: schema.TypeString},
   132  				Optional:      true,
   133  				ConflictsWith: []string{"forbidden_account_ids"},
   134  				Set: func(v interface{}) int {
   135  					return hashcode.String(v.(string))
   136  				},
   137  			},
   138  
   139  			"forbidden_account_ids": &schema.Schema{
   140  				Type:          schema.TypeSet,
   141  				Elem:          &schema.Schema{Type: schema.TypeString},
   142  				Optional:      true,
   143  				ConflictsWith: []string{"allowed_account_ids"},
   144  				Set: func(v interface{}) int {
   145  					return hashcode.String(v.(string))
   146  				},
   147  			},
   148  		},
   149  
   150  		ResourcesMap: map[string]*schema.Resource{
   151  			"aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(),
   152  			"aws_autoscaling_group":            resourceAwsAutoscalingGroup(),
   153  			"aws_autoscaling_notification":     resourceAwsAutoscalingNotification(),
   154  			"aws_autoscaling_policy":           resourceAwsAutoscalingPolicy(),
   155  			"aws_cloudwatch_metric_alarm":      resourceAwsCloudWatchMetricAlarm(),
   156  			"aws_customer_gateway":             resourceAwsCustomerGateway(),
   157  			"aws_db_instance":                  resourceAwsDbInstance(),
   158  			"aws_db_parameter_group":           resourceAwsDbParameterGroup(),
   159  			"aws_db_security_group":            resourceAwsDbSecurityGroup(),
   160  			"aws_db_subnet_group":              resourceAwsDbSubnetGroup(),
   161  			"aws_dynamodb_table":               resourceAwsDynamoDbTable(),
   162  			"aws_ebs_volume":                   resourceAwsEbsVolume(),
   163  			"aws_ecs_cluster":                  resourceAwsEcsCluster(),
   164  			"aws_ecs_service":                  resourceAwsEcsService(),
   165  			"aws_ecs_task_definition":          resourceAwsEcsTaskDefinition(),
   166  			"aws_eip":                          resourceAwsEip(),
   167  			"aws_elasticache_cluster":          resourceAwsElasticacheCluster(),
   168  			"aws_elasticache_parameter_group":  resourceAwsElasticacheParameterGroup(),
   169  			"aws_elasticache_security_group":   resourceAwsElasticacheSecurityGroup(),
   170  			"aws_elasticache_subnet_group":     resourceAwsElasticacheSubnetGroup(),
   171  			"aws_elb":                          resourceAwsElb(),
   172  			"aws_flow_log":                     resourceAwsFlowLog(),
   173  			"aws_iam_access_key":               resourceAwsIamAccessKey(),
   174  			"aws_iam_group_policy":             resourceAwsIamGroupPolicy(),
   175  			"aws_iam_group":                    resourceAwsIamGroup(),
   176  			"aws_iam_group_membership":         resourceAwsIamGroupMembership(),
   177  			"aws_iam_instance_profile":         resourceAwsIamInstanceProfile(),
   178  			"aws_iam_policy":                   resourceAwsIamPolicy(),
   179  			"aws_iam_policy_attachment":        resourceAwsIamPolicyAttachment(),
   180  			"aws_iam_role_policy":              resourceAwsIamRolePolicy(),
   181  			"aws_iam_role":                     resourceAwsIamRole(),
   182  			"aws_iam_server_certificate":       resourceAwsIAMServerCertificate(),
   183  			"aws_iam_user_policy":              resourceAwsIamUserPolicy(),
   184  			"aws_iam_user":                     resourceAwsIamUser(),
   185  			"aws_instance":                     resourceAwsInstance(),
   186  			"aws_internet_gateway":             resourceAwsInternetGateway(),
   187  			"aws_key_pair":                     resourceAwsKeyPair(),
   188  			"aws_kinesis_stream":               resourceAwsKinesisStream(),
   189  			"aws_lambda_function":              resourceAwsLambdaFunction(),
   190  			"aws_launch_configuration":         resourceAwsLaunchConfiguration(),
   191  			"aws_lb_cookie_stickiness_policy":  resourceAwsLBCookieStickinessPolicy(),
   192  			"aws_main_route_table_association": resourceAwsMainRouteTableAssociation(),
   193  			"aws_network_acl":                  resourceAwsNetworkAcl(),
   194  			"aws_network_interface":            resourceAwsNetworkInterface(),
   195  			"aws_proxy_protocol_policy":        resourceAwsProxyProtocolPolicy(),
   196  			"aws_route53_delegation_set":       resourceAwsRoute53DelegationSet(),
   197  			"aws_route53_record":               resourceAwsRoute53Record(),
   198  			"aws_route53_zone_association":     resourceAwsRoute53ZoneAssociation(),
   199  			"aws_route53_zone":                 resourceAwsRoute53Zone(),
   200  			"aws_route53_health_check":         resourceAwsRoute53HealthCheck(),
   201  			"aws_route_table":                  resourceAwsRouteTable(),
   202  			"aws_route_table_association":      resourceAwsRouteTableAssociation(),
   203  			"aws_s3_bucket":                    resourceAwsS3Bucket(),
   204  			"aws_security_group":               resourceAwsSecurityGroup(),
   205  			"aws_security_group_rule":          resourceAwsSecurityGroupRule(),
   206  			"aws_spot_instance_request":        resourceAwsSpotInstanceRequest(),
   207  			"aws_sqs_queue":                    resourceAwsSqsQueue(),
   208  			"aws_sns_topic":                    resourceAwsSnsTopic(),
   209  			"aws_sns_topic_subscription":       resourceAwsSnsTopicSubscription(),
   210  			"aws_subnet":                       resourceAwsSubnet(),
   211  			"aws_volume_attachment":            resourceAwsVolumeAttachment(),
   212  			"aws_vpc_dhcp_options_association": resourceAwsVpcDhcpOptionsAssociation(),
   213  			"aws_vpc_dhcp_options":             resourceAwsVpcDhcpOptions(),
   214  			"aws_vpc_peering_connection":       resourceAwsVpcPeeringConnection(),
   215  			"aws_vpc":                          resourceAwsVpc(),
   216  			"aws_vpc_endpoint":                 resourceAwsVpcEndpoint(),
   217  			"aws_vpn_connection":               resourceAwsVpnConnection(),
   218  			"aws_vpn_connection_route":         resourceAwsVpnConnectionRoute(),
   219  			"aws_vpn_gateway":                  resourceAwsVpnGateway(),
   220  		},
   221  
   222  		ConfigureFunc: providerConfigure,
   223  	}
   224  }
   225  
   226  var descriptions map[string]string
   227  
   228  func init() {
   229  	descriptions = map[string]string{
   230  		"region": "The region where AWS operations will take place. Examples\n" +
   231  			"are us-east-1, us-west-2, etc.",
   232  
   233  		"access_key": "The access key for API operations. You can retrieve this\n" +
   234  			"from the 'Security & Credentials' section of the AWS console.",
   235  
   236  		"secret_key": "The secret key for API operations. You can retrieve this\n" +
   237  			"from the 'Security & Credentials' section of the AWS console.",
   238  
   239  		"token": "session token. A session token is only required if you are\n" +
   240  			"using temporary security credentials.",
   241  
   242  		"max_retries": "The maximum number of times an AWS API request is\n" +
   243  			"being executed. If the API request still fails, an error is\n" +
   244  			"thrown.",
   245  	}
   246  }
   247  
   248  func providerConfigure(d *schema.ResourceData) (interface{}, error) {
   249  	config := Config{
   250  		AccessKey:  d.Get("access_key").(string),
   251  		SecretKey:  d.Get("secret_key").(string),
   252  		Token:      d.Get("token").(string),
   253  		Region:     d.Get("region").(string),
   254  		MaxRetries: d.Get("max_retries").(int),
   255  	}
   256  
   257  	if v, ok := d.GetOk("allowed_account_ids"); ok {
   258  		config.AllowedAccountIds = v.(*schema.Set).List()
   259  	}
   260  
   261  	if v, ok := d.GetOk("forbidden_account_ids"); ok {
   262  		config.ForbiddenAccountIds = v.(*schema.Set).List()
   263  	}
   264  
   265  	return config.Client()
   266  }