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) }
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) }
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) }
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) }