func resource_aws_route_table_association_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn rs := s.MergeDiff(d) log.Printf( "[INFO] Replacing route table association: %s => %s", rs.Attributes["subnet_id"], rs.Attributes["route_table_id"]) resp, err := ec2conn.ReassociateRouteTable( rs.ID, rs.Attributes["route_table_id"]) if err != nil { ec2err, ok := err.(*ec2.Error) if ok && ec2err.Code == "InvalidAssociationID.NotFound" { // Not found, so just create a new one return resource_aws_route_table_association_create(s, d, meta) } return s, err } // Update the ID rs.ID = resp.AssociationId log.Printf("[INFO] Association ID: %s", rs.ID) rs.Dependencies = []terraform.ResourceDependency{ terraform.ResourceDependency{ID: rs.Attributes["route_table_id"]}, } return rs, nil }
func resource_aws_instance_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn rs := s.MergeDiff(d) modify := false opts := new(ec2.ModifyInstance) if attr, ok := d.Attributes["source_dest_check"]; ok { modify = true opts.SourceDestCheck = attr.New != "" && attr.New != "false" opts.SetSourceDestCheck = true rs.Attributes["source_dest_check"] = strconv.FormatBool( opts.SourceDestCheck) } if modify { log.Printf("[INFO] Modifing instance %s: %#v", s.ID, opts) if _, err := ec2conn.ModifyInstance(s.ID, opts); err != nil { return s, err } // TODO(mitchellh): wait for the attributes we modified to // persist the change... } return rs, nil }
func resource_heroku_addon_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client rs := s.MergeDiff(d) app := rs.Attributes["app"] if attr, ok := d.Attributes["plan"]; ok { ad, err := client.AddonUpdate( app, rs.ID, attr.New) if err != nil { return s, err } // Store the new ID rs.ID = ad.Id } addon, err := resource_heroku_addon_retrieve(app, rs.ID, client) if err != nil { return rs, err } return resource_heroku_addon_update_state(rs, addon) }
func resource_heroku_domain_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) app := rs.Attributes["app"] hostname := rs.Attributes["hostname"] log.Printf("[DEBUG] Domain create configuration: %#v, %#v", app, hostname) do, err := client.DomainCreate(app, hostname) if err != nil { return s, err } rs.ID = do.Id rs.Attributes["hostname"] = do.Hostname rs.Attributes["cname"] = fmt.Sprintf("%s.herokuapp.com", app) log.Printf("[INFO] Domain ID: %s", rs.ID) return rs, nil }
func resource_heroku_drain_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) app := rs.Attributes["app"] url := rs.Attributes["url"] log.Printf("[DEBUG] Drain create configuration: %#v, %#v", app, url) dr, err := client.LogDrainCreate(app, url) if err != nil { return s, err } rs.ID = dr.Id rs.Attributes["url"] = dr.URL rs.Attributes["token"] = dr.Token log.Printf("[INFO] Drain ID: %s", rs.ID) return rs, nil }
func resource_digitalocean_domain_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) // Build up our creation options opts := digitalocean.CreateDomain{ Name: rs.Attributes["name"], IPAddress: rs.Attributes["ip_address"], } log.Printf("[DEBUG] Domain create configuration: %#v", opts) name, err := client.CreateDomain(&opts) if err != nil { return nil, fmt.Errorf("Error creating Domain: %s", err) } rs.ID = name log.Printf("[INFO] Domain Name: %s", name) return rs, nil }
func resource_aws_s3_bucket_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) s3conn := p.s3conn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) // Get the bucket and optional acl bucket := rs.Attributes["bucket"] acl := "private" if other, ok := rs.Attributes["acl"]; ok { acl = other } log.Printf("[DEBUG] S3 bucket create: %s, ACL: %s", bucket, acl) s3Bucket := s3conn.Bucket(bucket) err := s3Bucket.PutBucket(s3.ACL(acl)) if err != nil { return nil, fmt.Errorf("Error creating S3 bucket: %s", err) } // Assign the bucket name as the resource ID rs.ID = bucket return rs, nil }
func resource_aws_route_table_association_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn rs := s.MergeDiff(d) log.Printf( "[INFO] Creating route table association: %s => %s", rs.Attributes["subnet_id"], rs.Attributes["route_table_id"]) resp, err := ec2conn.AssociateRouteTable( rs.Attributes["route_table_id"], rs.Attributes["subnet_id"]) if err != nil { return nil, err } // Set the ID and return rs.ID = resp.AssociationId log.Printf("[INFO] Association ID: %s", rs.ID) rs.Dependencies = []terraform.ResourceDependency{ terraform.ResourceDependency{ID: rs.Attributes["route_table_id"]}, } return rs, nil }
func resource_digitalocean_record_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client rs := s.MergeDiff(d) updateRecord := digitalocean.UpdateRecord{} if attr, ok := d.Attributes["name"]; ok { updateRecord.Name = attr.New } log.Printf("[DEBUG] record update configuration: %#v", updateRecord) err := client.UpdateRecord(rs.Attributes["domain"], rs.ID, &updateRecord) if err != nil { return rs, fmt.Errorf("Failed to update record: %s", err) } record, err := resource_digitalocean_record_retrieve(rs.Attributes["domain"], rs.ID, client) if err != nil { return rs, fmt.Errorf("Couldn't find record: %s", err) } return resource_digitalocean_record_update_state(rs, record) }
func resource_cloudflare_record_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client rs := s.MergeDiff(d) // Cloudflare requires we send all values // for an update request, so we just // merge out diff and send the current // state of affairs to them updateRecord := cloudflare.UpdateRecord{ Name: rs.Attributes["name"], Content: rs.Attributes["value"], Type: rs.Attributes["type"], Ttl: rs.Attributes["ttl"], Priority: rs.Attributes["priority"], } log.Printf("[DEBUG] record update configuration: %#v", updateRecord) err := client.UpdateRecord(rs.Attributes["domain"], rs.ID, &updateRecord) if err != nil { return rs, fmt.Errorf("Failed to update record: %s", err) } record, err := resource_cloudflare_record_retrieve(rs.Attributes["domain"], rs.ID, client) if err != nil { return rs, fmt.Errorf("Couldn't find record: %s", err) } return resource_cloudflare_record_update_state(rs, record) }
func resource_aws_subnet_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff so that we have all the proper attributes s = s.MergeDiff(d) // Create the Subnet createOpts := &ec2.CreateSubnet{ AvailabilityZone: s.Attributes["availability_zone"], CidrBlock: s.Attributes["cidr_block"], VpcId: s.Attributes["vpc_id"], } log.Printf("[DEBUG] Subnet create config: %#v", createOpts) resp, err := ec2conn.CreateSubnet(createOpts) if err != nil { return nil, fmt.Errorf("Error creating subnet: %s", err) } // Get the ID and store it subnet := &resp.Subnet s.ID = subnet.SubnetId log.Printf("[INFO] Subnet ID: %s", s.ID) // Wait for the Subnet to become available log.Printf( "[DEBUG] Waiting for subnet (%s) to become available", s.ID) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "available", Refresh: SubnetStateRefreshFunc(ec2conn, s.ID), Timeout: 10 * time.Minute, } subnetRaw, err := stateConf.WaitForState() if err != nil { return s, fmt.Errorf( "Error waiting for subnet (%s) to become available: %s", s.ID, err) } // Map public ip on launch must be set in another API call if attr := s.Attributes["map_public_ip_on_launch"]; attr == "true" { modifyOpts := &ec2.ModifySubnetAttribute{ SubnetId: s.ID, MapPublicIpOnLaunch: true, } log.Printf("[DEBUG] Subnet modify attributes: %#v", modifyOpts) _, err := ec2conn.ModifySubnetAttribute(modifyOpts) if err != nil { return nil, fmt.Errorf("Error modify subnet attributes: %s", err) } } // Update our attributes and return return resource_aws_subnet_update_state(s, subnetRaw.(*ec2.Subnet)) }
func resource_aws_internet_gateway_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff so we have the latest attributes rs := s.MergeDiff(d) // A note on the states below: the AWS docs (as of July, 2014) say // that the states would be: attached, attaching, detached, detaching, // but when running, I noticed that the state is usually "available" when // it is attached. // If we're already attached, detach it first if err := resource_aws_internet_gateway_detach(ec2conn, s); err != nil { return s, err } // Set the VPC ID to empty since we're detached at this point delete(rs.Attributes, "vpc_id") if attr, ok := d.Attributes["vpc_id"]; ok && attr.New != "" { err := resource_aws_internet_gateway_attach(ec2conn, s, attr.New) if err != nil { return rs, err } rs.Attributes["vpc_id"] = attr.New } return resource_aws_internet_gateway_update_state(rs, nil) }
func resource_openstack_compute_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) serversApi, err := gophercloud.ServersApi(client.AccessProvider, gophercloud.ApiCriteria{ Name: "nova", UrlChoice: gophercloud.PublicURL, }) if err != nil { return nil, err } if attr, ok := d.Attributes["name"]; ok { _, err := serversApi.UpdateServer(rs.ID, gophercloud.NewServerSettings{ Name: attr.New, }) if err != nil { return nil, err } rs.Attributes["name"] = attr.New } if attr, ok := d.Attributes["flavor_ref"]; ok { err := serversApi.ResizeServer(rs.Attributes["id"], rs.Attributes["name"], attr.New, "") if err != nil { return nil, err } stateConf := &resource.StateChangeConf{ Pending: []string{"ACTIVE"}, Target: "VERIFY_RESIZE", Refresh: WaitForServerState(serversApi, rs.Attributes["id"]), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } _, err = stateConf.WaitForState() if err != nil { return nil, err } err = serversApi.ConfirmResize(rs.Attributes["id"]) } return rs, nil }
func resource_aws_launch_configuration_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) autoscalingconn := p.autoscalingconn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) var err error createLaunchConfigurationOpts := autoscaling.CreateLaunchConfiguration{} if rs.Attributes["image_id"] != "" { createLaunchConfigurationOpts.ImageId = rs.Attributes["image_id"] } if rs.Attributes["instance_type"] != "" { createLaunchConfigurationOpts.InstanceType = rs.Attributes["instance_type"] } if rs.Attributes["instance_id"] != "" { createLaunchConfigurationOpts.InstanceId = rs.Attributes["instance_id"] } if rs.Attributes["key_name"] != "" { createLaunchConfigurationOpts.KeyName = rs.Attributes["key_name"] } if err != nil { return nil, fmt.Errorf("Error parsing configuration: %s", err) } if _, ok := rs.Attributes["security_groups.#"]; ok { createLaunchConfigurationOpts.SecurityGroups = expandStringList(flatmap.Expand( rs.Attributes, "security_groups").([]interface{})) } createLaunchConfigurationOpts.Name = rs.Attributes["name"] log.Printf("[DEBUG] autoscaling create launch configuration: %#v", createLaunchConfigurationOpts) _, err = autoscalingconn.CreateLaunchConfiguration(&createLaunchConfigurationOpts) if err != nil { return nil, fmt.Errorf("Error creating launch configuration: %s", err) } rs.ID = rs.Attributes["name"] log.Printf("[INFO] launch configuration ID: %s", rs.ID) g, err := resource_aws_launch_configuration_retrieve(rs.ID, autoscalingconn) if err != nil { return rs, err } return resource_aws_launch_configuration_update_state(rs, g) }
func resource_aws_r53_record_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) conn := p.route53 // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) // Get the record rec, err := resource_aws_r53_build_record_set(rs) if err != nil { return rs, err } // Create the new records req := &route53.ChangeResourceRecordSetsRequest{ Comment: "Managed by Terraform", Changes: []route53.Change{ route53.Change{ Action: "UPSERT", Record: *rec, }, }, } zone := rs.Attributes["zone_id"] log.Printf("[DEBUG] Creating resource records for zone: %s, name: %s", zone, rs.Attributes["name"]) resp, err := conn.ChangeResourceRecordSets(zone, req) if err != nil { return rs, err } // Generate an ID rs.ID = fmt.Sprintf("%s_%s_%s", zone, rs.Attributes["name"], rs.Attributes["type"]) rs.Dependencies = []terraform.ResourceDependency{ terraform.ResourceDependency{ID: zone}, } // Wait until we are done wait := resource.StateChangeConf{ Delay: 30 * time.Second, Pending: []string{"PENDING"}, Target: "INSYNC", Timeout: 10 * time.Minute, MinTimeout: 5 * time.Second, Refresh: func() (result interface{}, state string, err error) { return resource_aws_r53_wait(conn, resp.ChangeInfo.ID) }, } _, err = wait.WaitForState() if err != nil { return rs, err } return rs, nil }
func resource_heroku_app_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) // Build up our creation options opts := heroku.AppCreateOpts{} if attr := rs.Attributes["name"]; attr != "" { opts.Name = &attr } if attr := rs.Attributes["region"]; attr != "" { opts.Region = &attr } if attr := rs.Attributes["stack"]; attr != "" { opts.Stack = &attr } log.Printf("[DEBUG] App create configuration: %#v", opts) a, err := client.AppCreate(&opts) if err != nil { return s, err } rs.ID = a.Name log.Printf("[INFO] App ID: %s", rs.ID) if attr, ok := rs.Attributes["config_vars.#"]; ok && attr == "1" { vs := flatmap.Expand( rs.Attributes, "config_vars").([]interface{}) err = update_config_vars(rs.ID, vs, client) if err != nil { return rs, err } } app, err := resource_heroku_app_retrieve(rs.ID, client) if err != nil { return rs, err } return resource_heroku_app_update_state(rs, app) }
func resource_heroku_app_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client rs := s.MergeDiff(d) if attr, ok := d.Attributes["name"]; ok { opts := heroku.AppUpdateOpts{ Name: &attr.New, } renamedApp, err := client.AppUpdate(rs.ID, &opts) if err != nil { return s, err } // Store the new ID rs.ID = renamedApp.Name } attr, ok := s.Attributes["config_vars.#"] // If the config var block was removed, nuke all config vars if ok && attr == "1" { vs := flatmap.Expand( rs.Attributes, "config_vars").([]interface{}) err := update_config_vars(rs.ID, vs, client) if err != nil { return rs, err } } else if ok && attr == "0" { log.Println("[INFO] Config vars removed, removing all vars") err := update_config_vars(rs.ID, make([]interface{}, 0), client) if err != nil { return rs, err } } app, err := resource_heroku_app_retrieve(rs.ID, client) if err != nil { return rs, err } return resource_heroku_app_update_state(rs, app) }
func resource_heroku_addon_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { addonLock.Lock() defer addonLock.Unlock() p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) app := rs.Attributes["app"] plan := rs.Attributes["plan"] opts := heroku.AddonCreateOpts{} if attr, ok := rs.Attributes["config.#"]; ok && attr == "1" { vs := flatmap.Expand( rs.Attributes, "config").([]interface{}) config := make(map[string]string) for k, v := range vs[0].(map[string]interface{}) { config[k] = v.(string) } opts.Config = &config } log.Printf("[DEBUG] Addon create configuration: %#v, %#v, %#v", app, plan, opts) a, err := client.AddonCreate(app, plan, &opts) if err != nil { return s, err } rs.ID = a.Id log.Printf("[INFO] Addon ID: %s", rs.ID) addon, err := resource_heroku_addon_retrieve(app, rs.ID, client) if err != nil { return rs, err } return resource_heroku_addon_update_state(rs, addon) }
func resource_aws_eip_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) // By default, we're not in a VPC vpc := false domainOpt := "" if rs.Attributes["vpc"] == "true" { vpc = true domainOpt = "vpc" } allocOpts := ec2.AllocateAddress{ Domain: domainOpt, } log.Printf("[DEBUG] EIP create configuration: %#v", allocOpts) allocResp, err := ec2conn.AllocateAddress(&allocOpts) if err != nil { return nil, fmt.Errorf("Error creating EIP: %s", err) } // Assign the eips (unique) allocation id for use later // the EIP api has a conditional unique ID (really), so // if we're in a VPC we need to save the ID as such, otherwise // it defaults to using the public IP log.Printf("[DEBUG] EIP Allocate: %#v", allocResp) if allocResp.AllocationId != "" { rs.ID = allocResp.AllocationId rs.Attributes["vpc"] = "true" } else { rs.ID = allocResp.PublicIp } log.Printf("[INFO] EIP ID: %s (vpc: %v)", rs.ID, vpc) return resource_aws_eip_update(rs, d, meta) }
func resource_aws_eip_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) vpc := strings.Contains(rs.ID, "eipalloc") // If we have an instance to register, do it instanceId := rs.Attributes["instance"] // Only register with an instance if we have one if instanceId != "" { assocOpts := ec2.AssociateAddress{ InstanceId: instanceId, PublicIp: rs.ID, } // more unique ID conditionals if vpc { assocOpts = ec2.AssociateAddress{ InstanceId: instanceId, AllocationId: rs.ID, PublicIp: "", } } log.Printf("[DEBUG] EIP associate configuration: %#v (vpc: %v)", assocOpts, vpc) _, err := ec2conn.AssociateAddress(&assocOpts) if err != nil { return rs, fmt.Errorf("Failure associating instances: %s", err) } } address, err := resource_aws_eip_retrieve_address(rs.ID, vpc, ec2conn) if err != nil { return rs, err } return resource_aws_eip_update_state(rs, address) }
func resource_aws_vpc_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff so that we have all the proper attributes s = s.MergeDiff(d) // Create the VPC createOpts := &ec2.CreateVpc{ CidrBlock: s.Attributes["cidr_block"], } log.Printf("[DEBUG] VPC create config: %#v", createOpts) vpcResp, err := ec2conn.CreateVpc(createOpts) if err != nil { return nil, fmt.Errorf("Error creating VPC: %s", err) } // Get the ID and store it vpc := &vpcResp.VPC log.Printf("[INFO] VPC ID: %s", vpc.VpcId) s.ID = vpc.VpcId // Wait for the VPC to become available log.Printf( "[DEBUG] Waiting for VPC (%s) to become available", s.ID) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "available", Refresh: VPCStateRefreshFunc(ec2conn, s.ID), Timeout: 10 * time.Minute, } vpcRaw, err := stateConf.WaitForState() if err != nil { return s, fmt.Errorf( "Error waiting for VPC (%s) to become available: %s", s.ID, err) } // Update our attributes and return return resource_aws_vpc_update_state(s, vpcRaw.(*ec2.VPC)) }
func resource_aws_autoscaling_group_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) autoscalingconn := p.autoscalingconn rs := s.MergeDiff(d) opts := autoscaling.UpdateAutoScalingGroup{ Name: rs.ID, } var err error if _, ok := d.Attributes["min_size"]; ok { opts.MinSize, err = strconv.Atoi(rs.Attributes["min_size"]) opts.SetMinSize = true } if _, ok := d.Attributes["max_size"]; ok { opts.MaxSize, err = strconv.Atoi(rs.Attributes["max_size"]) opts.SetMaxSize = true } if err != nil { return s, fmt.Errorf("Error parsing configuration: %s", err) } log.Printf("[DEBUG] AutoScaling Group update configuration: %#v", opts) _, err = autoscalingconn.UpdateAutoScalingGroup(&opts) if err != nil { return rs, fmt.Errorf("Error updating AutoScaling group: %s", err) } g, err := resource_aws_autoscaling_group_retrieve(rs.ID, autoscalingconn) if err != nil { return rs, err } return resource_aws_autoscaling_group_update_state(rs, g) }
func resource_aws_r53_zone_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) r53 := p.route53 // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) req := &route53.CreateHostedZoneRequest{ Name: rs.Attributes["name"], Comment: "Managed by Terraform", } log.Printf("[DEBUG] Creating Route53 hosted zone: %s", req.Name) resp, err := r53.CreateHostedZone(req) if err != nil { return rs, err } // Store the zone_id zone := route53.CleanZoneID(resp.HostedZone.ID) rs.ID = zone rs.Attributes["zone_id"] = zone // Wait until we are done initializing wait := resource.StateChangeConf{ Delay: 30 * time.Second, Pending: []string{"PENDING"}, Target: "INSYNC", Timeout: 10 * time.Minute, MinTimeout: 5 * time.Second, Refresh: func() (result interface{}, state string, err error) { return resource_aws_r53_wait(r53, resp.ChangeInfo.ID) }, } _, err = wait.WaitForState() if err != nil { return rs, err } return rs, nil }
func resource_aws_vpc_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn rs := s.MergeDiff(d) log.Printf("[DEBUG] attributes: %#v", d.Attributes) if attr, ok := d.Attributes["enable_dns_support"]; ok { options := new(ec2.ModifyVpcAttribute) options.EnableDnsSupport = attr.New != "" && attr.New != "false" options.SetEnableDnsSupport = true rs.Attributes["enable_dns_support"] = strconv.FormatBool(options.EnableDnsSupport) log.Printf("[INFO] Modifying enable_dns_support vpc attribute for %s: %#v", s.ID, options) if _, err := ec2conn.ModifyVpcAttribute(s.ID, options); err != nil { return s, err } } if attr, ok := d.Attributes["enable_dns_hostnames"]; ok { options := new(ec2.ModifyVpcAttribute) options.EnableDnsHostnames = attr.New != "" && attr.New != "false" options.SetEnableDnsHostnames = true rs.Attributes["enable_dns_hostnames"] = strconv.FormatBool(options.EnableDnsHostnames) log.Printf("[INFO] Modifying enable_dns_hostnames vpc attribute for %s: %#v", s.ID, options) if _, err := ec2conn.ModifyVpcAttribute(s.ID, options); err != nil { return s, err } } return rs, nil }
func resource_dnsimple_record_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) var err error newRecord := dnsimple.ChangeRecord{ Name: rs.Attributes["name"], Value: rs.Attributes["value"], Type: rs.Attributes["type"], } if attr, ok := rs.Attributes["ttl"]; ok { newRecord.Ttl = attr } log.Printf("[DEBUG] record create configuration: %#v", newRecord) recId, err := client.CreateRecord(rs.Attributes["domain"], &newRecord) if err != nil { return nil, fmt.Errorf("Failed to create record: %s", err) } rs.ID = recId log.Printf("[INFO] record ID: %s", rs.ID) record, err := resource_dnsimple_record_retrieve(rs.Attributes["domain"], rs.ID, client) if err != nil { return nil, fmt.Errorf("Couldn't find record: %s", err) } return resource_dnsimple_record_update_state(rs, record) }
func resource_digitalocean_record_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) client := p.client // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) var err error newRecord := digitalocean.CreateRecord{ Type: rs.Attributes["type"], Name: rs.Attributes["name"], Data: rs.Attributes["value"], Priority: rs.Attributes["priority"], Port: rs.Attributes["port"], Weight: rs.Attributes["weight"], } log.Printf("[DEBUG] record create configuration: %#v", newRecord) recId, err := client.CreateRecord(rs.Attributes["domain"], &newRecord) if err != nil { return nil, fmt.Errorf("Failed to create record: %s", err) } rs.ID = recId log.Printf("[INFO] Record ID: %s", rs.ID) record, err := resource_digitalocean_record_retrieve(rs.Attributes["domain"], rs.ID, client) if err != nil { return nil, fmt.Errorf("Couldn't find record: %s", err) } return resource_digitalocean_record_update_state(rs, record) }
func resource_aws_security_group_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) ec2conn := p.ec2conn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) securityGroupOpts := ec2.SecurityGroup{ Name: rs.Attributes["name"], } if rs.Attributes["vpc_id"] != "" { securityGroupOpts.VpcId = rs.Attributes["vpc_id"] } if rs.Attributes["description"] != "" { securityGroupOpts.Description = rs.Attributes["description"] } log.Printf("[DEBUG] Security Group create configuration: %#v", securityGroupOpts) createResp, err := ec2conn.CreateSecurityGroup(securityGroupOpts) if err != nil { return nil, fmt.Errorf("Error creating Security Group: %s", err) } rs.ID = createResp.Id group := createResp.SecurityGroup log.Printf("[INFO] Security Group ID: %s", rs.ID) // Wait for the security group to truly exist log.Printf( "[DEBUG] Waiting for SG (%s) to exist", s.ID) stateConf := &resource.StateChangeConf{ Pending: []string{""}, Target: "exists", Refresh: SGStateRefreshFunc(ec2conn, rs.ID), Timeout: 1 * time.Minute, } if _, err := stateConf.WaitForState(); err != nil { return s, fmt.Errorf( "Error waiting for SG (%s) to become available: %s", rs.ID, err) } // Expand the "ingress" array to goamz compat []ec2.IPPerm ingressRules := []ec2.IPPerm{} v, ok := flatmap.Expand(rs.Attributes, "ingress").([]interface{}) if ok { ingressRules, err = expandIPPerms(v) if err != nil { return rs, err } } if len(ingressRules) > 0 { _, err = ec2conn.AuthorizeSecurityGroup(group, ingressRules) if err != nil { return rs, fmt.Errorf("Error authorizing security group ingress rules: %s", err) } } return resource_aws_security_group_refresh(rs, meta) }
func resource_aws_elb_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) elbconn := p.elbconn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) // The name specified for the ELB. This is also our unique ID // we save to state if the creation is successful (amazon verifies // it is unique) elbName := rs.Attributes["name"] // Expand the "listener" array to goamz compat []elb.Listener v := flatmap.Expand(rs.Attributes, "listener").([]interface{}) listeners, err := expandListeners(v) if err != nil { return nil, err } // Provision the elb elbOpts := &elb.CreateLoadBalancer{ LoadBalancerName: elbName, Listeners: listeners, } if _, ok := rs.Attributes["availability_zones.#"]; ok { v = flatmap.Expand(rs.Attributes, "availability_zones").([]interface{}) zones := expandStringList(v) elbOpts.AvailZone = zones } log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts) _, err = elbconn.CreateLoadBalancer(elbOpts) if err != nil { return nil, fmt.Errorf("Error creating ELB: %s", err) } // Assign the elb's unique identifier for use later rs.ID = elbName log.Printf("[INFO] ELB ID: %s", elbName) if _, ok := rs.Attributes["instances.#"]; ok { // If we have any instances, we need to register them v = flatmap.Expand(rs.Attributes, "instances").([]interface{}) instances := expandStringList(v) if len(instances) > 0 { registerInstancesOpts := elb.RegisterInstancesWithLoadBalancer{ LoadBalancerName: elbName, Instances: instances, } _, err := elbconn.RegisterInstancesWithLoadBalancer(®isterInstancesOpts) if err != nil { return rs, fmt.Errorf("Failure registering instances: %s", err) } } } if _, ok := rs.Attributes["health_check.#"]; ok { v := flatmap.Expand(rs.Attributes, "health_check").([]interface{}) health_check := v[0].(map[string]interface{}) healthyThreshold, err := strconv.ParseInt(health_check["healthy_threshold"].(string), 0, 0) unhealthyThreshold, err := strconv.ParseInt(health_check["unhealthy_threshold"].(string), 0, 0) interval, err := strconv.ParseInt(health_check["interval"].(string), 0, 0) timeout, err := strconv.ParseInt(health_check["timeout"].(string), 0, 0) if err != nil { return nil, err } configureHealthCheckOpts := elb.ConfigureHealthCheck{ LoadBalancerName: elbName, Check: elb.HealthCheck{ HealthyThreshold: healthyThreshold, UnhealthyThreshold: unhealthyThreshold, Interval: interval, Target: health_check["target"].(string), Timeout: timeout, }, } _, err = elbconn.ConfigureHealthCheck(&configureHealthCheckOpts) if err != nil { return rs, fmt.Errorf("Failure configuring health check: %s", err) } } loadBalancer, err := resource_aws_elb_retrieve_balancer(rs.ID, elbconn) if err != nil { return rs, err } return resource_aws_elb_update_state(rs, loadBalancer) }
func resource_aws_elb_update( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) elbconn := p.elbconn rs := s.MergeDiff(d) // If we currently have instances, or did have instances, // we want to figure out what to add and remove from the load // balancer if attr, ok := d.Attributes["instances.#"]; ok && attr.Old != "" { // The new state of instances merged with the diff mergedInstances := expandStringList(flatmap.Expand( rs.Attributes, "instances").([]interface{})) // The state before the diff merge previousInstances := expandStringList(flatmap.Expand( s.Attributes, "instances").([]interface{})) // keep track of what instances we are removing, and which // we are adding var toRemove []string var toAdd []string for _, instanceId := range mergedInstances { for _, prevId := range previousInstances { // If the merged instance ID existed // previously, we don't have to do anything if instanceId == prevId { continue // Otherwise, we need to add it to the load balancer } else { toAdd = append(toAdd, instanceId) } } } for i, instanceId := range toAdd { for _, prevId := range previousInstances { // If the instance ID we are adding existed // previously, we want to not add it, but rather remove // it if instanceId == prevId { toRemove = append(toRemove, instanceId) toAdd = append(toAdd[:i], toAdd[i+1:]...) // Otherwise, we continue adding it to the ELB } else { continue } } } if len(toAdd) > 0 { registerInstancesOpts := elb.RegisterInstancesWithLoadBalancer{ LoadBalancerName: rs.ID, Instances: toAdd, } _, err := elbconn.RegisterInstancesWithLoadBalancer(®isterInstancesOpts) if err != nil { return s, fmt.Errorf("Failure registering instances: %s", err) } } if len(toRemove) > 0 { deRegisterInstancesOpts := elb.DeregisterInstancesFromLoadBalancer{ LoadBalancerName: rs.ID, Instances: toRemove, } _, err := elbconn.DeregisterInstancesFromLoadBalancer(&deRegisterInstancesOpts) if err != nil { return s, fmt.Errorf("Failure deregistering instances: %s", err) } } } loadBalancer, err := resource_aws_elb_retrieve_balancer(rs.ID, elbconn) if err != nil { return s, err } return resource_aws_elb_update_state(rs, loadBalancer) }
func resource_aws_autoscaling_group_create( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) autoscalingconn := p.autoscalingconn // Merge the diff into the state so that we have all the attributes // properly. rs := s.MergeDiff(d) var err error autoScalingGroupOpts := autoscaling.CreateAutoScalingGroup{} if rs.Attributes["min_size"] != "" { autoScalingGroupOpts.MinSize, err = strconv.Atoi(rs.Attributes["min_size"]) autoScalingGroupOpts.SetMinSize = true } if rs.Attributes["max_size"] != "" { autoScalingGroupOpts.MaxSize, err = strconv.Atoi(rs.Attributes["max_size"]) autoScalingGroupOpts.SetMaxSize = true } if rs.Attributes["default_cooldown"] != "" { autoScalingGroupOpts.DefaultCooldown, err = strconv.Atoi(rs.Attributes["default_cooldown"]) autoScalingGroupOpts.SetDefaultCooldown = true } if rs.Attributes["desired_capacity"] != "" { autoScalingGroupOpts.DesiredCapacity, err = strconv.Atoi(rs.Attributes["desired_capacity"]) autoScalingGroupOpts.SetDesiredCapacity = true } if rs.Attributes["health_check_grace_period"] != "" { autoScalingGroupOpts.HealthCheckGracePeriod, err = strconv.Atoi(rs.Attributes["health_check_grace_period"]) autoScalingGroupOpts.SetHealthCheckGracePeriod = true } if err != nil { return nil, fmt.Errorf("Error parsing configuration: %s", err) } if _, ok := rs.Attributes["availability_zones.#"]; ok { autoScalingGroupOpts.AvailZone = expandStringList(flatmap.Expand( rs.Attributes, "availability_zones").([]interface{})) } if _, ok := rs.Attributes["load_balancers.#"]; ok { autoScalingGroupOpts.LoadBalancerNames = expandStringList(flatmap.Expand( rs.Attributes, "load_balancers").([]interface{})) } if _, ok := rs.Attributes["vpc_identifier.#"]; ok { autoScalingGroupOpts.VPCZoneIdentifier = expandStringList(flatmap.Expand( rs.Attributes, "vpc_identifier").([]interface{})) } autoScalingGroupOpts.Name = rs.Attributes["name"] autoScalingGroupOpts.HealthCheckType = rs.Attributes["health_check_type"] autoScalingGroupOpts.LaunchConfigurationName = rs.Attributes["launch_configuration"] log.Printf("[DEBUG] AutoScaling Group create configuration: %#v", autoScalingGroupOpts) _, err = autoscalingconn.CreateAutoScalingGroup(&autoScalingGroupOpts) if err != nil { return nil, fmt.Errorf("Error creating AutoScaling Group: %s", err) } rs.ID = rs.Attributes["name"] rs.Dependencies = []terraform.ResourceDependency{ terraform.ResourceDependency{ID: rs.Attributes["launch_configuration"]}, } log.Printf("[INFO] AutoScaling Group ID: %s", rs.ID) g, err := resource_aws_autoscaling_group_retrieve(rs.ID, autoscalingconn) if err != nil { return rs, err } return resource_aws_autoscaling_group_update_state(rs, g) }