func resourceAwsKeyPairCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	var keyName string
	if v, ok := d.GetOk("key_name"); ok {
		keyName = v.(string)
	} else if v, ok := d.GetOk("key_name_prefix"); ok {
		keyName = resource.PrefixedUniqueId(v.(string))
	} else {
		keyName = resource.UniqueId()
	}

	publicKey := d.Get("public_key").(string)
	req := &ec2.ImportKeyPairInput{
		KeyName:           aws.String(keyName),
		PublicKeyMaterial: []byte(publicKey),
	}
	resp, err := conn.ImportKeyPair(req)
	if err != nil {
		return fmt.Errorf("Error import KeyPair: %s", err)
	}

	d.SetId(*resp.KeyName)
	return nil
}
func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ecsconn

	input := ecs.CreateServiceInput{
		ServiceName:    aws.String(d.Get("name").(string)),
		TaskDefinition: aws.String(d.Get("task_definition").(string)),
		DesiredCount:   aws.Int64(int64(d.Get("desired_count").(int))),
		ClientToken:    aws.String(resource.UniqueId()),
	}

	if v, ok := d.GetOk("cluster"); ok {
		input.Cluster = aws.String(v.(string))
	}

	loadBalancers := expandEcsLoadBalancers(d.Get("load_balancer").(*schema.Set).List())
	if len(loadBalancers) > 0 {
		log.Printf("[DEBUG] Adding ECS load balancers: %s", loadBalancers)
		input.LoadBalancers = loadBalancers
	}
	if v, ok := d.GetOk("iam_role"); ok {
		input.Role = aws.String(v.(string))
	}

	log.Printf("[DEBUG] Creating ECS service: %s", input)

	// Retry due to AWS IAM policy eventual consistency
	// See https://github.com/hashicorp/terraform/issues/2869
	var out *ecs.CreateServiceOutput
	var err error
	err = resource.Retry(2*time.Minute, func() error {
		out, err = conn.CreateService(&input)

		if err != nil {
			ec2err, ok := err.(awserr.Error)
			if !ok {
				return &resource.RetryError{Err: err}
			}
			if ec2err.Code() == "InvalidParameterException" {
				log.Printf("[DEBUG] Trying to create ECS service again: %q",
					ec2err.Message())
				return err
			}

			return &resource.RetryError{Err: err}
		}

		return nil
	})
	if err != nil {
		return err
	}

	service := *out.Service

	log.Printf("[DEBUG] ECS service created: %s", *service.ServiceArn)
	d.SetId(*service.ServiceArn)
	d.Set("cluster", *service.ClusterArn)

	return resourceAwsEcsServiceUpdate(d, meta)
}
Esempio n. 3
0
func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	request := &iam.CreateRoleInput{
		Path:                     aws.String(d.Get("path").(string)),
		RoleName:                 aws.String(name),
		AssumeRolePolicyDocument: aws.String(d.Get("assume_role_policy").(string)),
	}

	var createResp *iam.CreateRoleOutput
	err := resource.Retry(10*time.Second, func() *resource.RetryError {
		var err error
		createResp, err = iamconn.CreateRole(request)
		// IAM roles can take ~10 seconds to propagate in AWS:
		// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
		if isAWSErr(err, "MalformedPolicyDocument", "Invalid principal in policy") {
			return resource.RetryableError(err)
		}
		return resource.NonRetryableError(err)
	})
	if err != nil {
		return fmt.Errorf("Error creating IAM Role %s: %s", name, err)
	}
	return resourceAwsIamRoleReadResult(d, createResp.Role)
}
func TestAccAWSAPIGatewayDomainName_basic(t *testing.T) {
	var conf apigateway.DomainName

	// Our test cert is for a wildcard on this domain
	name := fmt.Sprintf("%s.tf-acc.invalid", resource.UniqueId())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSAPIGatewayDomainNameDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSAPIGatewayDomainNameConfigCreate(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAPIGatewayDomainNameExists("aws_api_gateway_domain_name.test", &conf),
					resource.TestCheckResourceAttr(
						"aws_api_gateway_domain_name.test", "certificate_body", testAccAWSAPIGatewayCertBody,
					),
					resource.TestCheckResourceAttr(
						"aws_api_gateway_domain_name.test", "certificate_chain", testAccAWSAPIGatewayCertChain,
					),
					resource.TestCheckResourceAttr(
						"aws_api_gateway_domain_name.test", "certificate_name", "tf-acc-apigateway-domain-name",
					),
					resource.TestCheckResourceAttr(
						"aws_api_gateway_domain_name.test", "certificate_private_key", testAccAWSAPIGatewayCertPrivateKey,
					),
					resource.TestCheckResourceAttr(
						"aws_api_gateway_domain_name.test", "domain_name", name,
					),
				),
			},
		},
	})
}
func resourceAwsIamInstanceProfileCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	request := &iam.CreateInstanceProfileInput{
		InstanceProfileName: aws.String(name),
		Path:                aws.String(d.Get("path").(string)),
	}

	var err error
	response, err := iamconn.CreateInstanceProfile(request)
	if err == nil {
		err = instanceProfileReadResult(d, response.InstanceProfile)
	}
	if err != nil {
		return fmt.Errorf("Error creating IAM instance profile %s: %s", name, err)
	}

	return instanceProfileSetRoles(d, iamconn)
}
func resourceAwsRoute53DelegationSetCreate(d *schema.ResourceData, meta interface{}) error {
	r53 := meta.(*AWSClient).r53conn

	callerRef := resource.UniqueId()
	if v, ok := d.GetOk("reference_name"); ok {
		callerRef = strings.Join([]string{
			v.(string), "-", callerRef,
		}, "")
	}
	input := &route53.CreateReusableDelegationSetInput{
		CallerReference: aws.String(callerRef),
	}

	log.Printf("[DEBUG] Creating Route53 reusable delegation set: %#v", input)
	out, err := r53.CreateReusableDelegationSet(input)
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] Route53 reusable delegation set created: %#v", out)

	set := out.DelegationSet
	d.SetId(cleanDelegationSetId(*set.Id))
	d.Set("name_servers", expandNameServers(set.NameServers))
	return nil
}
func resourceAwsCloudWatchEventTargetCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudwatcheventsconn

	rule := d.Get("rule").(string)

	var targetId string
	if v, ok := d.GetOk("target_id"); ok {
		targetId = v.(string)
	} else {
		targetId = resource.UniqueId()
		d.Set("target_id", targetId)
	}

	input := buildPutTargetInputStruct(d)
	log.Printf("[DEBUG] Creating CloudWatch Event Target: %s", input)
	out, err := conn.PutTargets(input)
	if err != nil {
		return fmt.Errorf("Creating CloudWatch Event Target failed: %s", err)
	}

	if len(out.FailedEntries) > 0 {
		return fmt.Errorf("Creating CloudWatch Event Target failed: %s",
			out.FailedEntries)
	}

	id := rule + "-" + targetId
	d.SetId(id)

	log.Printf("[INFO] CloudWatch Event Target %q created", d.Id())

	return resourceAwsCloudWatchEventTargetRead(d, meta)
}
func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	request := &iam.CreateRoleInput{
		Path:                     aws.String(d.Get("path").(string)),
		RoleName:                 aws.String(name),
		AssumeRolePolicyDocument: aws.String(d.Get("assume_role_policy").(string)),
	}

	var createResp *iam.CreateRoleOutput
	err := resource.Retry(30*time.Second, func() *resource.RetryError {
		var err error
		createResp, err = iamconn.CreateRole(request)
		// IAM users (referenced in Principal field of assume policy)
		// can take ~30 seconds to propagate in AWS
		if isAWSErr(err, "MalformedPolicyDocument", "Invalid principal in policy") {
			return resource.RetryableError(err)
		}
		return resource.NonRetryableError(err)
	})
	if err != nil {
		return fmt.Errorf("Error creating IAM Role %s: %s", name, err)
	}
	return resourceAwsIamRoleReadResult(d, createResp.Role)
}
func resourceAwsRDSClusterInstanceCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn
	tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))

	createOpts := &rds.CreateDBInstanceInput{
		DBInstanceClass:     aws.String(d.Get("instance_class").(string)),
		DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)),
		Engine:              aws.String("aurora"),
		PubliclyAccessible:  aws.Bool(d.Get("publicly_accessible").(bool)),
		Tags:                tags,
	}

	if attr, ok := d.GetOk("db_parameter_group_name"); ok {
		createOpts.DBParameterGroupName = aws.String(attr.(string))
	}

	if v := d.Get("identifier").(string); v != "" {
		createOpts.DBInstanceIdentifier = aws.String(v)
	} else {
		createOpts.DBInstanceIdentifier = aws.String(resource.UniqueId())
	}

	if attr, ok := d.GetOk("db_subnet_group_name"); ok {
		createOpts.DBSubnetGroupName = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("monitoring_role_arn"); ok {
		createOpts.MonitoringRoleArn = aws.String(attr.(string))
	}

	if attr, ok := d.GetOk("monitoring_interval"); ok {
		createOpts.MonitoringInterval = aws.Int64(int64(attr.(int)))
	}

	log.Printf("[DEBUG] Creating RDS DB Instance opts: %s", createOpts)
	resp, err := conn.CreateDBInstance(createOpts)
	if err != nil {
		return err
	}

	d.SetId(*resp.DBInstance.DBInstanceIdentifier)

	// reuse db_instance refresh func
	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating", "backing-up", "modifying"},
		Target:     []string{"available"},
		Refresh:    resourceAwsDbInstanceStateRefreshFunc(d, meta),
		Timeout:    40 * time.Minute,
		MinTimeout: 10 * time.Second,
		Delay:      10 * time.Second,
	}

	// Wait, catching any errors
	_, err = stateConf.WaitForState()
	if err != nil {
		return err
	}

	return resourceAwsRDSClusterInstanceRead(d, meta)
}
func resourceAwsIamPolicyCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	request := &iam.CreatePolicyInput{
		Description:    aws.String(d.Get("description").(string)),
		Path:           aws.String(d.Get("path").(string)),
		PolicyDocument: aws.String(d.Get("policy").(string)),
		PolicyName:     aws.String(name),
	}

	response, err := iamconn.CreatePolicy(request)
	if err != nil {
		return fmt.Errorf("Error creating IAM policy %s: %s", name, err)
	}

	return readIamPolicy(d, response.Policy)
}
func resourceAwsEfsFileSystemCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).efsconn

	referenceName := ""
	if v, ok := d.GetOk("reference_name"); ok {
		referenceName = v.(string) + "-"
	}
	token := referenceName + resource.UniqueId()
	fs, err := conn.CreateFileSystem(&efs.CreateFileSystemInput{
		CreationToken: aws.String(token),
	})
	if err != nil {
		return err
	}

	log.Printf("[DEBUG] Creating EFS file system: %s", *fs)
	d.SetId(*fs.FileSystemId)

	stateConf := &resource.StateChangeConf{
		Pending: []string{"creating"},
		Target:  "available",
		Refresh: func() (interface{}, string, error) {
			resp, err := conn.DescribeFileSystems(&efs.DescribeFileSystemsInput{
				FileSystemId: aws.String(d.Id()),
			})
			if err != nil {
				return nil, "error", err
			}

			if len(resp.FileSystems) < 1 {
				return nil, "not-found", fmt.Errorf("EFS file system %q not found", d.Id())
			}

			fs := resp.FileSystems[0]
			log.Printf("[DEBUG] current status of %q: %q", *fs.FileSystemId, *fs.LifeCycleState)
			return fs, *fs.LifeCycleState, nil
		},
		Timeout:    10 * time.Minute,
		Delay:      2 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for EFS file system (%q) to create: %q",
			d.Id(), err.Error())
	}
	log.Printf("[DEBUG] EFS file system created: %q", *fs.FileSystemId)

	return resourceAwsEfsFileSystemUpdate(d, meta)
}
func TestAccAWSAPIGatewayBasePath_basic(t *testing.T) {
	var conf apigateway.BasePathMapping

	// Our test cert is for a wildcard on this domain
	name := fmt.Sprintf("%s.tf-acc.invalid", resource.UniqueId())

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSAPIGatewayBasePathDestroy(name),
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccAWSAPIGatewayBasePathConfig(name),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSAPIGatewayBasePathExists("aws_api_gateway_base_path_mapping.test", name, &conf),
				),
			},
		},
	})
}
func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).iamconn

	var sslCertName string
	if v, ok := d.GetOk("name"); ok {
		sslCertName = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		sslCertName = resource.PrefixedUniqueId(v.(string))
	} else {
		sslCertName = resource.UniqueId()
	}

	createOpts := &iam.UploadServerCertificateInput{
		CertificateBody:       aws.String(d.Get("certificate_body").(string)),
		PrivateKey:            aws.String(d.Get("private_key").(string)),
		ServerCertificateName: aws.String(sslCertName),
	}

	if v, ok := d.GetOk("certificate_chain"); ok {
		createOpts.CertificateChain = aws.String(v.(string))
	}

	if v, ok := d.GetOk("path"); ok {
		createOpts.Path = aws.String(v.(string))
	}

	log.Printf("[DEBUG] Creating IAM Server Certificate with opts: %s", createOpts)
	resp, err := conn.UploadServerCertificate(createOpts)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			return fmt.Errorf("[WARN] Error uploading server certificate, error: %s: %s", awsErr.Code(), awsErr.Message())
		}
		return fmt.Errorf("[WARN] Error uploading server certificate, error: %s", err)
	}

	d.SetId(*resp.ServerCertificateMetadata.ServerCertificateId)
	d.Set("name", sslCertName)

	return resourceAwsIAMServerCertificateRead(d, meta)
}
Esempio n. 14
0
func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ecsconn

	input := ecs.CreateServiceInput{
		ServiceName:    aws.String(d.Get("name").(string)),
		TaskDefinition: aws.String(d.Get("task_definition").(string)),
		DesiredCount:   aws.Int64(int64(d.Get("desired_count").(int))),
		ClientToken:    aws.String(resource.UniqueId()),
	}

	if v, ok := d.GetOk("cluster"); ok {
		input.Cluster = aws.String(v.(string))
	}

	loadBalancers := expandEcsLoadBalancers(d.Get("load_balancer").(*schema.Set).List())
	if len(loadBalancers) > 0 {
		log.Printf("[DEBUG] Adding ECS load balancers: %s", loadBalancers)
		input.LoadBalancers = loadBalancers
	}
	if v, ok := d.GetOk("iam_role"); ok {
		input.Role = aws.String(v.(string))
	}

	log.Printf("[DEBUG] Creating ECS service: %s", input)
	out, err := conn.CreateService(&input)
	if err != nil {
		return err
	}

	service := *out.Service

	log.Printf("[DEBUG] ECS service created: %s", *service.ServiceARN)
	d.SetId(*service.ServiceARN)
	d.Set("cluster", *service.ClusterARN)

	return resourceAwsEcsServiceUpdate(d, meta)
}
Esempio n. 15
0
func resourceAwsIamRoleCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	request := &iam.CreateRoleInput{
		Path:                     aws.String(d.Get("path").(string)),
		RoleName:                 aws.String(name),
		AssumeRolePolicyDocument: aws.String(d.Get("assume_role_policy").(string)),
	}

	createResp, err := iamconn.CreateRole(request)
	if err != nil {
		return fmt.Errorf("Error creating IAM Role %s: %s", name, err)
	}
	return resourceAwsIamRoleReadResult(d, createResp.Role)
}
func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).r53conn

	healthConfig := &route53.HealthCheckConfig{
		Type: aws.String(d.Get("type").(string)),
	}

	if v, ok := d.GetOk("request_interval"); ok {
		healthConfig.RequestInterval = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("failure_threshold"); ok {
		healthConfig.FailureThreshold = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("fqdn"); ok {
		healthConfig.FullyQualifiedDomainName = aws.String(v.(string))
	}

	if v, ok := d.GetOk("search_string"); ok {
		healthConfig.SearchString = aws.String(v.(string))
	}

	if v, ok := d.GetOk("ip_address"); ok {
		healthConfig.IPAddress = aws.String(v.(string))
	}

	if v, ok := d.GetOk("port"); ok {
		healthConfig.Port = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("resource_path"); ok {
		healthConfig.ResourcePath = aws.String(v.(string))
	}

	if *healthConfig.Type != route53.HealthCheckTypeCalculated && *healthConfig.Type != route53.HealthCheckTypeCloudwatchMetric {
		if v, ok := d.GetOk("measure_latency"); ok {
			healthConfig.MeasureLatency = aws.Bool(v.(bool))
		}
	}

	if v, ok := d.GetOk("invert_healthcheck"); ok {
		healthConfig.Inverted = aws.Bool(v.(bool))
	}

	if *healthConfig.Type == route53.HealthCheckTypeCalculated {
		if v, ok := d.GetOk("child_healthchecks"); ok {
			healthConfig.ChildHealthChecks = expandStringList(v.(*schema.Set).List())
		}

		if v, ok := d.GetOk("child_health_threshold"); ok {
			healthConfig.HealthThreshold = aws.Int64(int64(v.(int)))
		}
	}

	if *healthConfig.Type == route53.HealthCheckTypeCloudwatchMetric {
		cloudwatchAlarmIdentifier := &route53.AlarmIdentifier{}

		if v, ok := d.GetOk("cloudwatch_alarm_name"); ok {
			cloudwatchAlarmIdentifier.Name = aws.String(v.(string))
		}

		if v, ok := d.GetOk("cloudwatch_alarm_region"); ok {
			cloudwatchAlarmIdentifier.Region = aws.String(v.(string))
		}

		healthConfig.AlarmIdentifier = cloudwatchAlarmIdentifier

		if v, ok := d.GetOk("insufficient_data_health_status"); ok {
			healthConfig.InsufficientDataHealthStatus = aws.String(v.(string))
		}
	}

	callerRef := resource.UniqueId()
	if v, ok := d.GetOk("reference_name"); ok {
		callerRef = fmt.Sprintf("%s-%s", v.(string), callerRef)
	}

	input := &route53.CreateHealthCheckInput{
		CallerReference:   aws.String(callerRef),
		HealthCheckConfig: healthConfig,
	}

	resp, err := conn.CreateHealthCheck(input)

	if err != nil {
		return err
	}

	d.SetId(*resp.HealthCheck.Id)

	if err := setTagsR53(conn, d, "healthcheck"); err != nil {
		return err
	}

	return resourceAwsRoute53HealthCheckRead(d, meta)
}
func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) error {
	// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RequestSpotFleet.html
	conn := meta.(*AWSClient).ec2conn

	launch_specs, err := buildAwsSpotFleetLaunchSpecifications(d, meta)
	if err != nil {
		return err
	}

	// http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetRequestConfigData
	spotFleetConfig := &ec2.SpotFleetRequestConfigData{
		IamFleetRole:                     aws.String(d.Get("iam_fleet_role").(string)),
		LaunchSpecifications:             launch_specs,
		SpotPrice:                        aws.String(d.Get("spot_price").(string)),
		TargetCapacity:                   aws.Int64(int64(d.Get("target_capacity").(int))),
		ClientToken:                      aws.String(resource.UniqueId()),
		TerminateInstancesWithExpiration: aws.Bool(d.Get("terminate_instances_with_expiration").(bool)),
	}

	if v, ok := d.GetOk("excess_capacity_termination_policy"); ok {
		spotFleetConfig.ExcessCapacityTerminationPolicy = aws.String(v.(string))
	}

	if v, ok := d.GetOk("allocation_strategy"); ok {
		spotFleetConfig.AllocationStrategy = aws.String(v.(string))
	} else {
		spotFleetConfig.AllocationStrategy = aws.String("lowestPrice")
	}

	if v, ok := d.GetOk("valid_from"); ok {
		valid_from, err := time.Parse(awsAutoscalingScheduleTimeLayout, v.(string))
		if err != nil {
			return err
		}
		spotFleetConfig.ValidFrom = &valid_from
	}

	if v, ok := d.GetOk("valid_until"); ok {
		valid_until, err := time.Parse(awsAutoscalingScheduleTimeLayout, v.(string))
		if err != nil {
			return err
		}
		spotFleetConfig.ValidUntil = &valid_until
	} else {
		valid_until := time.Now().Add(24 * time.Hour)
		spotFleetConfig.ValidUntil = &valid_until
	}

	// http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-RequestSpotFleetInput
	spotFleetOpts := &ec2.RequestSpotFleetInput{
		SpotFleetRequestConfig: spotFleetConfig,
		DryRun:                 aws.Bool(false),
	}

	log.Printf("[DEBUG] Requesting spot fleet with these opts: %+v", spotFleetOpts)
	resp, err := conn.RequestSpotFleet(spotFleetOpts)
	if err != nil {
		return fmt.Errorf("Error requesting spot fleet: %s", err)
	}

	d.SetId(*resp.SpotFleetRequestId)

	return resourceAwsSpotFleetRequestRead(d, meta)
}
func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ecsconn

	input := ecs.CreateServiceInput{
		ServiceName:    aws.String(d.Get("name").(string)),
		TaskDefinition: aws.String(d.Get("task_definition").(string)),
		DesiredCount:   aws.Int64(int64(d.Get("desired_count").(int))),
		ClientToken:    aws.String(resource.UniqueId()),
		DeploymentConfiguration: &ecs.DeploymentConfiguration{
			MaximumPercent:        aws.Int64(int64(d.Get("deployment_maximum_percent").(int))),
			MinimumHealthyPercent: aws.Int64(int64(d.Get("deployment_minimum_healthy_percent").(int))),
		},
	}

	if v, ok := d.GetOk("cluster"); ok {
		input.Cluster = aws.String(v.(string))
	}

	loadBalancers := expandEcsLoadBalancers(d.Get("load_balancer").(*schema.Set).List())
	if len(loadBalancers) > 0 {
		log.Printf("[DEBUG] Adding ECS load balancers: %s", loadBalancers)
		input.LoadBalancers = loadBalancers
	}
	if v, ok := d.GetOk("iam_role"); ok {
		input.Role = aws.String(v.(string))
	}

	strategies := d.Get("placement_strategy").(*schema.Set).List()
	if len(strategies) > 0 {
		var ps []*ecs.PlacementStrategy
		for _, raw := range strategies {
			p := raw.(map[string]interface{})
			ps = append(ps, &ecs.PlacementStrategy{
				Type:  aws.String(p["type"].(string)),
				Field: aws.String(p["field"].(string)),
			})
		}
		input.PlacementStrategy = ps
	}

	constraints := d.Get("placement_constraints").(*schema.Set).List()
	if len(constraints) > 0 {
		var pc []*ecs.PlacementConstraint
		for _, raw := range constraints {
			p := raw.(map[string]interface{})
			pc = append(pc, &ecs.PlacementConstraint{
				Type:       aws.String(p["type"].(string)),
				Expression: aws.String(p["expression"].(string)),
			})
		}
		input.PlacementConstraints = pc
	}

	log.Printf("[DEBUG] Creating ECS service: %s", input)

	// Retry due to AWS IAM policy eventual consistency
	// See https://github.com/hashicorp/terraform/issues/2869
	var out *ecs.CreateServiceOutput
	var err error
	err = resource.Retry(2*time.Minute, func() *resource.RetryError {
		out, err = conn.CreateService(&input)

		if err != nil {
			ec2err, ok := err.(awserr.Error)
			if !ok {
				return resource.NonRetryableError(err)
			}
			if ec2err.Code() == "InvalidParameterException" {
				log.Printf("[DEBUG] Trying to create ECS service again: %q",
					ec2err.Message())
				return resource.RetryableError(err)
			}

			return resource.NonRetryableError(err)
		}

		return nil
	})
	if err != nil {
		return err
	}

	service := *out.Service

	log.Printf("[DEBUG] ECS service created: %s", *service.ServiceArn)
	d.SetId(*service.ServiceArn)

	return resourceAwsEcsServiceUpdate(d, meta)
}
func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	region := d.Get("region").(string)
	databaseVersion := d.Get("database_version").(string)

	_settingsList := d.Get("settings").([]interface{})
	if len(_settingsList) > 1 {
		return fmt.Errorf("At most one settings block is allowed")
	}

	_settings := _settingsList[0].(map[string]interface{})
	settings := &sqladmin.Settings{
		Tier: _settings["tier"].(string),
	}

	if v, ok := _settings["activation_policy"]; ok {
		settings.ActivationPolicy = v.(string)
	}

	if v, ok := _settings["authorized_gae_applications"]; ok {
		settings.AuthorizedGaeApplications = make([]string, 0)
		for _, app := range v.([]interface{}) {
			settings.AuthorizedGaeApplications = append(settings.AuthorizedGaeApplications,
				app.(string))
		}
	}

	if v, ok := _settings["backup_configuration"]; ok {
		_backupConfigurationList := v.([]interface{})
		if len(_backupConfigurationList) > 1 {
			return fmt.Errorf("At most one backup_configuration block is allowed")
		}

		if len(_backupConfigurationList) == 1 && _backupConfigurationList[0] != nil {
			settings.BackupConfiguration = &sqladmin.BackupConfiguration{}
			_backupConfiguration := _backupConfigurationList[0].(map[string]interface{})

			if vp, okp := _backupConfiguration["binary_log_enabled"]; okp {
				settings.BackupConfiguration.BinaryLogEnabled = vp.(bool)
			}

			if vp, okp := _backupConfiguration["enabled"]; okp {
				settings.BackupConfiguration.Enabled = vp.(bool)
			}

			if vp, okp := _backupConfiguration["start_time"]; okp {
				settings.BackupConfiguration.StartTime = vp.(string)
			}
		}
	}

	if v, ok := _settings["crash_safe_replication"]; ok {
		settings.CrashSafeReplicationEnabled = v.(bool)
	}

	if v, ok := _settings["database_flags"]; ok {
		settings.DatabaseFlags = make([]*sqladmin.DatabaseFlags, 0)
		_databaseFlagsList := v.([]interface{})
		for _, _flag := range _databaseFlagsList {
			_entry := _flag.(map[string]interface{})
			flag := &sqladmin.DatabaseFlags{}
			if vp, okp := _entry["name"]; okp {
				flag.Name = vp.(string)
			}

			if vp, okp := _entry["value"]; okp {
				flag.Value = vp.(string)
			}

			settings.DatabaseFlags = append(settings.DatabaseFlags, flag)
		}
	}

	if v, ok := _settings["ip_configuration"]; ok {
		_ipConfigurationList := v.([]interface{})
		if len(_ipConfigurationList) > 1 {
			return fmt.Errorf("At most one ip_configuration block is allowed")
		}

		if len(_ipConfigurationList) == 1 && _ipConfigurationList[0] != nil {
			settings.IpConfiguration = &sqladmin.IpConfiguration{}
			_ipConfiguration := _ipConfigurationList[0].(map[string]interface{})

			if vp, okp := _ipConfiguration["ipv4_enabled"]; okp {
				settings.IpConfiguration.Ipv4Enabled = vp.(bool)
			}

			if vp, okp := _ipConfiguration["require_ssl"]; okp {
				settings.IpConfiguration.RequireSsl = vp.(bool)
			}

			if vp, okp := _ipConfiguration["authorized_networks"]; okp {
				settings.IpConfiguration.AuthorizedNetworks = make([]*sqladmin.AclEntry, 0)
				_authorizedNetworksList := vp.([]interface{})
				for _, _acl := range _authorizedNetworksList {
					_entry := _acl.(map[string]interface{})
					entry := &sqladmin.AclEntry{}

					if vpp, okpp := _entry["expiration_time"]; okpp {
						entry.ExpirationTime = vpp.(string)
					}

					if vpp, okpp := _entry["name"]; okpp {
						entry.Name = vpp.(string)
					}

					if vpp, okpp := _entry["value"]; okpp {
						entry.Value = vpp.(string)
					}

					settings.IpConfiguration.AuthorizedNetworks = append(
						settings.IpConfiguration.AuthorizedNetworks, entry)
				}
			}
		}
	}

	if v, ok := _settings["location_preference"]; ok {
		_locationPreferenceList := v.([]interface{})
		if len(_locationPreferenceList) > 1 {
			return fmt.Errorf("At most one location_preference block is allowed")
		}

		if len(_locationPreferenceList) == 1 && _locationPreferenceList[0] != nil {
			settings.LocationPreference = &sqladmin.LocationPreference{}
			_locationPreference := _locationPreferenceList[0].(map[string]interface{})

			if vp, okp := _locationPreference["follow_gae_application"]; okp {
				settings.LocationPreference.FollowGaeApplication = vp.(string)
			}

			if vp, okp := _locationPreference["zone"]; okp {
				settings.LocationPreference.Zone = vp.(string)
			}
		}
	}

	if v, ok := _settings["pricing_plan"]; ok {
		settings.PricingPlan = v.(string)
	}

	if v, ok := _settings["replication_type"]; ok {
		settings.ReplicationType = v.(string)
	}

	instance := &sqladmin.DatabaseInstance{
		Region:          region,
		Settings:        settings,
		DatabaseVersion: databaseVersion,
	}

	if v, ok := d.GetOk("name"); ok {
		instance.Name = v.(string)
	} else {
		instance.Name = resource.UniqueId()
		d.Set("name", instance.Name)
	}

	if v, ok := d.GetOk("replica_configuration"); ok {
		_replicaConfigurationList := v.([]interface{})
		if len(_replicaConfigurationList) > 1 {
			return fmt.Errorf("Only one replica_configuration block may be defined")
		}

		if len(_replicaConfigurationList) == 1 && _replicaConfigurationList[0] != nil {
			replicaConfiguration := &sqladmin.ReplicaConfiguration{}
			mySqlReplicaConfiguration := &sqladmin.MySqlReplicaConfiguration{}
			_replicaConfiguration := _replicaConfigurationList[0].(map[string]interface{})

			if vp, okp := _replicaConfiguration["ca_certificate"]; okp {
				mySqlReplicaConfiguration.CaCertificate = vp.(string)
			}

			if vp, okp := _replicaConfiguration["client_certificate"]; okp {
				mySqlReplicaConfiguration.ClientCertificate = vp.(string)
			}

			if vp, okp := _replicaConfiguration["client_key"]; okp {
				mySqlReplicaConfiguration.ClientKey = vp.(string)
			}

			if vp, okp := _replicaConfiguration["connect_retry_interval"]; okp {
				mySqlReplicaConfiguration.ConnectRetryInterval = int64(vp.(int))
			}

			if vp, okp := _replicaConfiguration["dump_file_path"]; okp {
				mySqlReplicaConfiguration.DumpFilePath = vp.(string)
			}

			if vp, okp := _replicaConfiguration["master_heartbeat_period"]; okp {
				mySqlReplicaConfiguration.MasterHeartbeatPeriod = int64(vp.(int))
			}

			if vp, okp := _replicaConfiguration["password"]; okp {
				mySqlReplicaConfiguration.Password = vp.(string)
			}

			if vp, okp := _replicaConfiguration["ssl_cipher"]; okp {
				mySqlReplicaConfiguration.SslCipher = vp.(string)
			}

			if vp, okp := _replicaConfiguration["username"]; okp {
				mySqlReplicaConfiguration.Username = vp.(string)
			}

			if vp, okp := _replicaConfiguration["verify_server_certificate"]; okp {
				mySqlReplicaConfiguration.VerifyServerCertificate = vp.(bool)
			}

			replicaConfiguration.MysqlReplicaConfiguration = mySqlReplicaConfiguration
			instance.ReplicaConfiguration = replicaConfiguration
		}
	}

	if v, ok := d.GetOk("master_instance_name"); ok {
		instance.MasterInstanceName = v.(string)
	}

	op, err := config.clientSqlAdmin.Instances.Insert(config.Project, instance).Do()
	if err != nil {
		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 409 {
			return fmt.Errorf("Error, the name %s is unavailable because it was used recently", instance.Name)
		} else {
			return fmt.Errorf("Error, failed to create instance %s: %s", instance.Name, err)
		}
	}

	err = sqladminOperationWait(config, op, "Create Instance")
	if err != nil {
		return err
	}

	return resourceSqlDatabaseInstanceRead(d, meta)
}
func resourceAwsEfsFileSystemCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).efsconn

	creationToken := ""
	if v, ok := d.GetOk("creation_token"); ok {
		creationToken = v.(string)
	} else {
		if v, ok := d.GetOk("reference_name"); ok {
			creationToken = resource.PrefixedUniqueId(fmt.Sprintf("%s-", v.(string)))
			log.Printf("[WARN] Using deprecated `reference_name' attribute.")
		} else {
			creationToken = resource.UniqueId()
		}
	}

	createOpts := &efs.CreateFileSystemInput{
		CreationToken: aws.String(creationToken),
	}

	if v, ok := d.GetOk("performance_mode"); ok {
		createOpts.PerformanceMode = aws.String(v.(string))
	}

	log.Printf("[DEBUG] EFS file system create options: %#v", *createOpts)
	fs, err := conn.CreateFileSystem(createOpts)
	if err != nil {
		return fmt.Errorf("Error creating EFS file system: %s", err)
	}

	d.SetId(*fs.FileSystemId)
	log.Printf("[INFO] EFS file system ID: %s", d.Id())

	stateConf := &resource.StateChangeConf{
		Pending: []string{"creating"},
		Target:  []string{"available"},
		Refresh: func() (interface{}, string, error) {
			resp, err := conn.DescribeFileSystems(&efs.DescribeFileSystemsInput{
				FileSystemId: aws.String(d.Id()),
			})
			if err != nil {
				return nil, "error", err
			}

			if len(resp.FileSystems) < 1 {
				return nil, "not-found", fmt.Errorf("EFS file system %q not found", d.Id())
			}

			fs := resp.FileSystems[0]
			log.Printf("[DEBUG] current status of %q: %q", *fs.FileSystemId, *fs.LifeCycleState)
			return fs, *fs.LifeCycleState, nil
		},
		Timeout:    10 * time.Minute,
		Delay:      2 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for EFS file system (%q) to create: %q",
			d.Id(), err.Error())
	}
	log.Printf("[DEBUG] EFS file system %q created.", d.Id())

	return resourceAwsEfsFileSystemUpdate(d, meta)
}
func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
	autoscalingconn := meta.(*AWSClient).autoscalingconn
	ec2conn := meta.(*AWSClient).ec2conn

	createLaunchConfigurationOpts := autoscaling.CreateLaunchConfigurationInput{
		LaunchConfigurationName: aws.String(d.Get("name").(string)),
		ImageID:                 aws.String(d.Get("image_id").(string)),
		InstanceType:            aws.String(d.Get("instance_type").(string)),
		EBSOptimized:            aws.Boolean(d.Get("ebs_optimized").(bool)),
	}

	if v, ok := d.GetOk("user_data"); ok {
		userData := base64.StdEncoding.EncodeToString([]byte(v.(string)))
		createLaunchConfigurationOpts.UserData = aws.String(userData)
	}

	if v, ok := d.GetOk("iam_instance_profile"); ok {
		createLaunchConfigurationOpts.IAMInstanceProfile = aws.String(v.(string))
	}

	if v, ok := d.GetOk("placement_tenancy"); ok {
		createLaunchConfigurationOpts.PlacementTenancy = aws.String(v.(string))
	}

	if v, ok := d.GetOk("associate_public_ip_address"); ok {
		createLaunchConfigurationOpts.AssociatePublicIPAddress = aws.Boolean(v.(bool))
	}

	if v, ok := d.GetOk("key_name"); ok {
		createLaunchConfigurationOpts.KeyName = aws.String(v.(string))
	}
	if v, ok := d.GetOk("spot_price"); ok {
		createLaunchConfigurationOpts.SpotPrice = aws.String(v.(string))
	}

	if v, ok := d.GetOk("security_groups"); ok {
		createLaunchConfigurationOpts.SecurityGroups = expandStringList(
			v.(*schema.Set).List(),
		)
	}

	var blockDevices []*autoscaling.BlockDeviceMapping

	if v, ok := d.GetOk("ebs_block_device"); ok {
		vL := v.(*schema.Set).List()
		for _, v := range vL {
			bd := v.(map[string]interface{})
			ebs := &autoscaling.EBS{
				DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)),
			}

			if v, ok := bd["snapshot_id"].(string); ok && v != "" {
				ebs.SnapshotID = aws.String(v)
			}

			if v, ok := bd["volume_size"].(int); ok && v != 0 {
				ebs.VolumeSize = aws.Long(int64(v))
			}

			if v, ok := bd["volume_type"].(string); ok && v != "" {
				ebs.VolumeType = aws.String(v)
			}

			if v, ok := bd["iops"].(int); ok && v > 0 {
				ebs.IOPS = aws.Long(int64(v))
			}

			blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
				DeviceName: aws.String(bd["device_name"].(string)),
				EBS:        ebs,
			})
		}
	}

	if v, ok := d.GetOk("ephemeral_block_device"); ok {
		vL := v.(*schema.Set).List()
		for _, v := range vL {
			bd := v.(map[string]interface{})
			blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
				DeviceName:  aws.String(bd["device_name"].(string)),
				VirtualName: aws.String(bd["virtual_name"].(string)),
			})
		}
	}

	if v, ok := d.GetOk("root_block_device"); ok {
		vL := v.(*schema.Set).List()
		if len(vL) > 1 {
			return fmt.Errorf("Cannot specify more than one root_block_device.")
		}
		for _, v := range vL {
			bd := v.(map[string]interface{})
			ebs := &autoscaling.EBS{
				DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)),
			}

			if v, ok := bd["volume_size"].(int); ok && v != 0 {
				ebs.VolumeSize = aws.Long(int64(v))
			}

			if v, ok := bd["volume_type"].(string); ok && v != "" {
				ebs.VolumeType = aws.String(v)
			}

			if v, ok := bd["iops"].(int); ok && v > 0 {
				ebs.IOPS = aws.Long(int64(v))
			}

			if dn, err := fetchRootDeviceName(d.Get("image_id").(string), ec2conn); err == nil {
				blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
					DeviceName: dn,
					EBS:        ebs,
				})
			} else {
				return err
			}
		}
	}

	if len(blockDevices) > 0 {
		createLaunchConfigurationOpts.BlockDeviceMappings = blockDevices
	}

	var lcName string
	if v, ok := d.GetOk("name"); ok {
		lcName = v.(string)
	} else {
		lcName = resource.UniqueId()
	}
	createLaunchConfigurationOpts.LaunchConfigurationName = aws.String(lcName)

	log.Printf(
		"[DEBUG] autoscaling create launch configuration: %#v", createLaunchConfigurationOpts)
	_, err := autoscalingconn.CreateLaunchConfiguration(&createLaunchConfigurationOpts)
	if err != nil {
		return fmt.Errorf("Error creating launch configuration: %s", err)
	}

	d.SetId(lcName)
	log.Printf("[INFO] launch configuration ID: %s", d.Id())

	// We put a Retry here since sometimes eventual consistency bites
	// us and we need to retry a few times to get the LC to load properly
	return resource.Retry(30*time.Second, func() error {
		return resourceAwsLaunchConfigurationRead(d, meta)
	})
}
func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	instanceProperties := &compute.InstanceProperties{}

	instanceProperties.CanIpForward = d.Get("can_ip_forward").(bool)
	instanceProperties.Description = d.Get("instance_description").(string)
	instanceProperties.MachineType = d.Get("machine_type").(string)
	disks, err := buildDisks(d, meta)
	if err != nil {
		return err
	}
	instanceProperties.Disks = disks
	metadata, err := resourceInstanceMetadata(d)
	if err != nil {
		return err
	}
	instanceProperties.Metadata = metadata
	networks, err := buildNetworks(d, meta)
	if err != nil {
		return err
	}
	instanceProperties.NetworkInterfaces = networks

	instanceProperties.Scheduling = &compute.Scheduling{}
	instanceProperties.Scheduling.OnHostMaintenance = "MIGRATE"

	if v, ok := d.GetOk("automatic_restart"); ok {
		instanceProperties.Scheduling.AutomaticRestart = v.(bool)
	}

	if v, ok := d.GetOk("on_host_maintenance"); ok {
		instanceProperties.Scheduling.OnHostMaintenance = v.(string)
	}

	forceSendFieldsScheduling := make([]string, 0, 3)
	var hasSendMaintenance bool
	hasSendMaintenance = false
	if v, ok := d.GetOk("scheduling"); ok {
		_schedulings := v.([]interface{})
		if len(_schedulings) > 1 {
			return fmt.Errorf("Error, at most one `scheduling` block can be defined")
		}
		_scheduling := _schedulings[0].(map[string]interface{})

		if vp, okp := _scheduling["automatic_restart"]; okp {
			instanceProperties.Scheduling.AutomaticRestart = vp.(bool)
			forceSendFieldsScheduling = append(forceSendFieldsScheduling, "AutomaticRestart")
		}

		if vp, okp := _scheduling["on_host_maintenance"]; okp {
			instanceProperties.Scheduling.OnHostMaintenance = vp.(string)
			forceSendFieldsScheduling = append(forceSendFieldsScheduling, "OnHostMaintenance")
			hasSendMaintenance = true
		}

		if vp, okp := _scheduling["preemptible"]; okp {
			instanceProperties.Scheduling.Preemptible = vp.(bool)
			forceSendFieldsScheduling = append(forceSendFieldsScheduling, "Preemptible")
			if vp.(bool) && !hasSendMaintenance {
				instanceProperties.Scheduling.OnHostMaintenance = "TERMINATE"
				forceSendFieldsScheduling = append(forceSendFieldsScheduling, "OnHostMaintenance")
			}
		}
	}
	instanceProperties.Scheduling.ForceSendFields = forceSendFieldsScheduling

	serviceAccountsCount := d.Get("service_account.#").(int)
	serviceAccounts := make([]*compute.ServiceAccount, 0, serviceAccountsCount)
	for i := 0; i < serviceAccountsCount; i++ {
		prefix := fmt.Sprintf("service_account.%d", i)

		scopesCount := d.Get(prefix + ".scopes.#").(int)
		scopes := make([]string, 0, scopesCount)
		for j := 0; j < scopesCount; j++ {
			scope := d.Get(fmt.Sprintf(prefix+".scopes.%d", j)).(string)
			scopes = append(scopes, canonicalizeServiceScope(scope))
		}

		serviceAccount := &compute.ServiceAccount{
			Email:  "default",
			Scopes: scopes,
		}

		serviceAccounts = append(serviceAccounts, serviceAccount)
	}
	instanceProperties.ServiceAccounts = serviceAccounts

	instanceProperties.Tags = resourceInstanceTags(d)

	var itName string
	if v, ok := d.GetOk("name"); ok {
		itName = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		itName = resource.PrefixedUniqueId(v.(string))
	} else {
		itName = resource.UniqueId()
	}
	instanceTemplate := compute.InstanceTemplate{
		Description: d.Get("description").(string),
		Properties:  instanceProperties,
		Name:        itName,
	}

	op, err := config.clientCompute.InstanceTemplates.Insert(
		project, &instanceTemplate).Do()
	if err != nil {
		return fmt.Errorf("Error creating instance: %s", err)
	}

	// Store the ID now
	d.SetId(instanceTemplate.Name)

	err = computeOperationWaitGlobal(config, op, project, "Creating Instance Template")
	if err != nil {
		return err
	}

	return resourceComputeInstanceTemplateRead(d, meta)
}
func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
	autoscalingconn := meta.(*AWSClient).autoscalingconn
	ec2conn := meta.(*AWSClient).ec2conn

	createLaunchConfigurationOpts := autoscaling.CreateLaunchConfigurationInput{
		LaunchConfigurationName: aws.String(d.Get("name").(string)),
		ImageId:                 aws.String(d.Get("image_id").(string)),
		InstanceType:            aws.String(d.Get("instance_type").(string)),
		EbsOptimized:            aws.Bool(d.Get("ebs_optimized").(bool)),
	}

	if v, ok := d.GetOk("user_data"); ok {
		userData := base64.StdEncoding.EncodeToString([]byte(v.(string)))
		createLaunchConfigurationOpts.UserData = aws.String(userData)
	}

	createLaunchConfigurationOpts.InstanceMonitoring = &autoscaling.InstanceMonitoring{
		Enabled: aws.Bool(d.Get("enable_monitoring").(bool)),
	}

	if v, ok := d.GetOk("iam_instance_profile"); ok {
		createLaunchConfigurationOpts.IamInstanceProfile = aws.String(v.(string))
	}

	if v, ok := d.GetOk("placement_tenancy"); ok {
		createLaunchConfigurationOpts.PlacementTenancy = aws.String(v.(string))
	}

	if v, ok := d.GetOk("associate_public_ip_address"); ok {
		createLaunchConfigurationOpts.AssociatePublicIpAddress = aws.Bool(v.(bool))
	}

	if v, ok := d.GetOk("key_name"); ok {
		createLaunchConfigurationOpts.KeyName = aws.String(v.(string))
	}
	if v, ok := d.GetOk("spot_price"); ok {
		createLaunchConfigurationOpts.SpotPrice = aws.String(v.(string))
	}

	if v, ok := d.GetOk("security_groups"); ok {
		createLaunchConfigurationOpts.SecurityGroups = expandStringList(
			v.(*schema.Set).List(),
		)
	}

	if v, ok := d.GetOk("vpc_classic_link_id"); ok {
		createLaunchConfigurationOpts.ClassicLinkVPCId = aws.String(v.(string))
	}

	if v, ok := d.GetOk("vpc_classic_link_security_groups"); ok {
		createLaunchConfigurationOpts.ClassicLinkVPCSecurityGroups = expandStringList(
			v.(*schema.Set).List(),
		)
	}

	var blockDevices []*autoscaling.BlockDeviceMapping

	// We'll use this to detect if we're declaring it incorrectly as an ebs_block_device.
	rootDeviceName, err := fetchRootDeviceName(d.Get("image_id").(string), ec2conn)
	if err != nil {
		return err
	}
	if rootDeviceName == nil {
		// We do this so the value is empty so we don't have to do nil checks later
		var blank string
		rootDeviceName = &blank
	}

	if v, ok := d.GetOk("ebs_block_device"); ok {
		vL := v.(*schema.Set).List()
		for _, v := range vL {
			bd := v.(map[string]interface{})
			ebs := &autoscaling.Ebs{
				DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)),
			}

			if v, ok := bd["snapshot_id"].(string); ok && v != "" {
				ebs.SnapshotId = aws.String(v)
			}

			if v, ok := bd["encrypted"].(bool); ok && v {
				ebs.Encrypted = aws.Bool(v)
			}

			if v, ok := bd["volume_size"].(int); ok && v != 0 {
				ebs.VolumeSize = aws.Int64(int64(v))
			}

			if v, ok := bd["volume_type"].(string); ok && v != "" {
				ebs.VolumeType = aws.String(v)
			}

			if v, ok := bd["iops"].(int); ok && v > 0 {
				ebs.Iops = aws.Int64(int64(v))
			}

			if *aws.String(bd["device_name"].(string)) == *rootDeviceName {
				return fmt.Errorf("Root device (%s) declared as an 'ebs_block_device'.  Use 'root_block_device' keyword.", *rootDeviceName)
			}

			blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
				DeviceName: aws.String(bd["device_name"].(string)),
				Ebs:        ebs,
			})
		}
	}

	if v, ok := d.GetOk("ephemeral_block_device"); ok {
		vL := v.(*schema.Set).List()
		for _, v := range vL {
			bd := v.(map[string]interface{})
			blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
				DeviceName:  aws.String(bd["device_name"].(string)),
				VirtualName: aws.String(bd["virtual_name"].(string)),
			})
		}
	}

	if v, ok := d.GetOk("root_block_device"); ok {
		vL := v.(*schema.Set).List()
		if len(vL) > 1 {
			return fmt.Errorf("Cannot specify more than one root_block_device.")
		}
		for _, v := range vL {
			bd := v.(map[string]interface{})
			ebs := &autoscaling.Ebs{
				DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)),
			}

			if v, ok := bd["volume_size"].(int); ok && v != 0 {
				ebs.VolumeSize = aws.Int64(int64(v))
			}

			if v, ok := bd["volume_type"].(string); ok && v != "" {
				ebs.VolumeType = aws.String(v)
			}

			if v, ok := bd["iops"].(int); ok && v > 0 {
				ebs.Iops = aws.Int64(int64(v))
			}

			if dn, err := fetchRootDeviceName(d.Get("image_id").(string), ec2conn); err == nil {
				if dn == nil {
					return fmt.Errorf(
						"Expected to find a Root Device name for AMI (%s), but got none",
						d.Get("image_id").(string))
				}
				blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
					DeviceName: dn,
					Ebs:        ebs,
				})
			} else {
				return err
			}
		}
	}

	if len(blockDevices) > 0 {
		createLaunchConfigurationOpts.BlockDeviceMappings = blockDevices
	}

	var lcName string
	if v, ok := d.GetOk("name"); ok {
		lcName = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		lcName = resource.PrefixedUniqueId(v.(string))
	} else {
		lcName = resource.UniqueId()
	}
	createLaunchConfigurationOpts.LaunchConfigurationName = aws.String(lcName)

	log.Printf(
		"[DEBUG] autoscaling create launch configuration: %s", createLaunchConfigurationOpts)

	// IAM profiles can take ~10 seconds to propagate in AWS:
	// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role-console
	err = resource.Retry(30*time.Second, func() *resource.RetryError {
		_, err := autoscalingconn.CreateLaunchConfiguration(&createLaunchConfigurationOpts)
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if strings.Contains(awsErr.Message(), "Invalid IamInstanceProfile") {
					return resource.RetryableError(err)
				}
				if strings.Contains(awsErr.Message(), "You are not authorized to perform this operation") {
					return resource.RetryableError(err)
				}
			}
			return resource.NonRetryableError(err)
		}
		return nil
	})

	if err != nil {
		return fmt.Errorf("Error creating launch configuration: %s", err)
	}

	d.SetId(lcName)
	log.Printf("[INFO] launch configuration ID: %s", d.Id())

	// We put a Retry here since sometimes eventual consistency bites
	// us and we need to retry a few times to get the LC to load properly
	return resource.Retry(30*time.Second, func() *resource.RetryError {
		err := resourceAwsLaunchConfigurationRead(d, meta)
		if err != nil {
			return resource.RetryableError(err)
		}
		return nil
	})
}
func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) error {
	// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RequestSpotFleet.html
	conn := meta.(*AWSClient).ec2conn

	launch_specs, err := buildAwsSpotFleetLaunchSpecifications(d, meta)
	if err != nil {
		return err
	}

	// http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetRequestConfigData
	spotFleetConfig := &ec2.SpotFleetRequestConfigData{
		IamFleetRole:                     aws.String(d.Get("iam_fleet_role").(string)),
		LaunchSpecifications:             launch_specs,
		SpotPrice:                        aws.String(d.Get("spot_price").(string)),
		TargetCapacity:                   aws.Int64(int64(d.Get("target_capacity").(int))),
		ClientToken:                      aws.String(resource.UniqueId()),
		TerminateInstancesWithExpiration: aws.Bool(d.Get("terminate_instances_with_expiration").(bool)),
	}

	if v, ok := d.GetOk("excess_capacity_termination_policy"); ok {
		spotFleetConfig.ExcessCapacityTerminationPolicy = aws.String(v.(string))
	}

	if v, ok := d.GetOk("allocation_strategy"); ok {
		spotFleetConfig.AllocationStrategy = aws.String(v.(string))
	} else {
		spotFleetConfig.AllocationStrategy = aws.String("lowestPrice")
	}

	if v, ok := d.GetOk("valid_from"); ok {
		valid_from, err := time.Parse(awsAutoscalingScheduleTimeLayout, v.(string))
		if err != nil {
			return err
		}
		spotFleetConfig.ValidFrom = &valid_from
	}

	if v, ok := d.GetOk("valid_until"); ok {
		valid_until, err := time.Parse(awsAutoscalingScheduleTimeLayout, v.(string))
		if err != nil {
			return err
		}
		spotFleetConfig.ValidUntil = &valid_until
	} else {
		valid_until := time.Now().Add(24 * time.Hour)
		spotFleetConfig.ValidUntil = &valid_until
	}

	// http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-RequestSpotFleetInput
	spotFleetOpts := &ec2.RequestSpotFleetInput{
		SpotFleetRequestConfig: spotFleetConfig,
		DryRun:                 aws.Bool(false),
	}

	log.Printf("[DEBUG] Requesting spot fleet with these opts: %+v", spotFleetOpts)

	// Since IAM is eventually consistent, we retry creation as a newly created role may not
	// take effect immediately, resulting in an InvalidSpotFleetRequestConfig error
	var resp *ec2.RequestSpotFleetOutput
	err = resource.Retry(1*time.Minute, func() *resource.RetryError {
		var err error
		resp, err = conn.RequestSpotFleet(spotFleetOpts)

		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				// IAM is eventually consistent :/
				if awsErr.Code() == "InvalidSpotFleetRequestConfig" {
					return resource.RetryableError(
						fmt.Errorf("[WARN] Error creating Spot fleet request, retrying: %s", err))
				}
			}
			return resource.NonRetryableError(err)
		}
		return nil
	})

	if err != nil {
		return fmt.Errorf("Error requesting spot fleet: %s", err)
	}

	d.SetId(*resp.SpotFleetRequestId)

	log.Printf("[INFO] Spot Fleet Request ID: %s", d.Id())
	log.Println("[INFO] Waiting for Spot Fleet Request to be active")
	stateConf := &resource.StateChangeConf{
		Pending:    []string{"submitted"},
		Target:     []string{"active"},
		Refresh:    resourceAwsSpotFleetRequestStateRefreshFunc(d, meta),
		Timeout:    10 * time.Minute,
		MinTimeout: 10 * time.Second,
		Delay:      30 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return err
	}

	return resourceAwsSpotFleetRequestRead(d, meta)
}
func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	securityGroupOpts := &ec2.CreateSecurityGroupInput{}

	if v, ok := d.GetOk("vpc_id"); ok {
		securityGroupOpts.VpcId = aws.String(v.(string))
	}

	if v := d.Get("description"); v != nil {
		securityGroupOpts.Description = aws.String(v.(string))
	}

	var groupName string
	if v, ok := d.GetOk("name"); ok {
		groupName = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		groupName = resource.PrefixedUniqueId(v.(string))
	} else {
		groupName = resource.UniqueId()
	}
	securityGroupOpts.GroupName = aws.String(groupName)

	var err error
	log.Printf(
		"[DEBUG] Security Group create configuration: %#v", securityGroupOpts)
	createResp, err := conn.CreateSecurityGroup(securityGroupOpts)
	if err != nil {
		return fmt.Errorf("Error creating Security Group: %s", err)
	}

	d.SetId(*createResp.GroupId)

	log.Printf("[INFO] Security Group ID: %s", d.Id())

	// Wait for the security group to truly exist
	log.Printf(
		"[DEBUG] Waiting for Security Group (%s) to exist",
		d.Id())
	stateConf := &resource.StateChangeConf{
		Pending: []string{""},
		Target:  []string{"exists"},
		Refresh: SGStateRefreshFunc(conn, d.Id()),
		Timeout: 1 * time.Minute,
	}

	resp, err := stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Security Group (%s) to become available: %s",
			d.Id(), err)
	}

	// AWS defaults all Security Groups to have an ALLOW ALL egress rule. Here we
	// revoke that rule, so users don't unknowingly have/use it.
	group := resp.(*ec2.SecurityGroup)
	if group.VpcId != nil && *group.VpcId != "" {
		log.Printf("[DEBUG] Revoking default egress rule for Security Group for %s", d.Id())

		req := &ec2.RevokeSecurityGroupEgressInput{
			GroupId: createResp.GroupId,
			IpPermissions: []*ec2.IpPermission{
				&ec2.IpPermission{
					FromPort: aws.Int64(int64(0)),
					ToPort:   aws.Int64(int64(0)),
					IpRanges: []*ec2.IpRange{
						&ec2.IpRange{
							CidrIp: aws.String("0.0.0.0/0"),
						},
					},
					IpProtocol: aws.String("-1"),
				},
			},
		}

		if _, err = conn.RevokeSecurityGroupEgress(req); err != nil {
			return fmt.Errorf(
				"Error revoking default egress rule for Security Group (%s): %s",
				d.Id(), err)
		}

	}

	return resourceAwsSecurityGroupUpdate(d, meta)
}