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_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 (p *ResourceProvisioner) Apply(s *terraform.ResourceState, c *terraform.ResourceConfig) error { // Ensure the connection type is SSH if err := helper.VerifySSH(s); err != nil { return err } // Get the SSH configuration conf, err := helper.ParseSSHConfig(s) if err != nil { return err } // Collect the scripts scripts, err := p.collectScripts(c) if err != nil { return err } for _, s := range scripts { defer s.Close() } // Copy and execute each script if err := p.runScripts(conf, scripts); err != nil { return err } return 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_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_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_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_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_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_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_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_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_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_aws_security_group_update_state( s *terraform.ResourceState, sg *ec2.SecurityGroupInfo) (*terraform.ResourceState, error) { s.Attributes["description"] = sg.Description s.Attributes["name"] = sg.Name s.Attributes["vpc_id"] = sg.VpcId s.Attributes["owner_id"] = sg.OwnerId // Flatten our ingress values toFlatten := make(map[string]interface{}) toFlatten["ingress"] = flattenIPPerms(sg.IPPerms) for k, v := range flatmap.Flatten(toFlatten) { s.Attributes[k] = v } s.Dependencies = nil if s.Attributes["vpc_id"] != "" { s.Dependencies = append(s.Dependencies, terraform.ResourceDependency{ID: s.Attributes["vpc_id"]}, ) } return s, 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_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_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_instance_update_state( s *terraform.ResourceState, instance *ec2.Instance) (*terraform.ResourceState, error) { s.Attributes["availability_zone"] = instance.AvailZone s.Attributes["key_name"] = instance.KeyName s.Attributes["public_dns"] = instance.DNSName s.Attributes["public_ip"] = instance.PublicIpAddress s.Attributes["private_dns"] = instance.PrivateDNSName s.Attributes["private_ip"] = instance.PrivateIpAddress s.Attributes["subnet_id"] = instance.SubnetId s.Dependencies = nil // Extract the existing security groups useID := false if raw := flatmap.Expand(s.Attributes, "security_groups"); raw != nil { if sgs, ok := raw.([]interface{}); ok { for _, sg := range sgs { str, ok := sg.(string) if !ok { continue } if strings.HasPrefix(str, "sg-") { useID = true break } } } } // Build up the security groups sgs := make([]string, len(instance.SecurityGroups)) for i, sg := range instance.SecurityGroups { if instance.SubnetId != "" && useID { sgs[i] = sg.Id } else { sgs[i] = sg.Name } s.Dependencies = append(s.Dependencies, terraform.ResourceDependency{ID: sg.Id}, ) } flatmap.Map(s.Attributes).Merge(flatmap.Flatten(map[string]interface{}{ "security_groups": sgs, })) if instance.SubnetId != "" { s.Dependencies = append(s.Dependencies, terraform.ResourceDependency{ID: instance.SubnetId}, ) } return s, 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_aws_security_group_update_state( s *terraform.ResourceState, sg *ec2.SecurityGroupInfo) (*terraform.ResourceState, error) { s.Attributes["description"] = sg.Description s.Attributes["name"] = sg.Name s.Attributes["vpc_id"] = sg.VpcId s.Attributes["owner_id"] = sg.OwnerId // Flatten our ingress values toFlatten := make(map[string]interface{}) ingressRules := make([]map[string]interface{}, 0, len(sg.IPPerms)) for _, perm := range sg.IPPerms { n := make(map[string]interface{}) n["from_port"] = perm.FromPort n["protocol"] = perm.Protocol n["to_port"] = perm.ToPort if len(perm.SourceIPs) > 0 { n["cidr_blocks"] = perm.SourceIPs } if len(perm.SourceGroups) > 0 { // We depend on other security groups for _, v := range perm.SourceGroups { s.Dependencies = append(s.Dependencies, terraform.ResourceDependency{ID: v.Id}, ) } n["security_groups"] = flattenSecurityGroups(perm.SourceGroups) } // Reverse the order, as Amazon sorts it the reverse of how we created // it. ingressRules = append([]map[string]interface{}{n}, ingressRules...) } toFlatten["ingress"] = ingressRules for k, v := range flatmap.Flatten(toFlatten) { s.Attributes[k] = v } if s.Attributes["vpc_id"] != "" { s.Dependencies = append(s.Dependencies, terraform.ResourceDependency{ID: s.Attributes["vpc_id"]}, ) } return s, nil }
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) }
// Apply performs a create or update depending on the diff, and calls // the proper function on the matching Resource. func (m *Map) Apply( s *terraform.ResourceState, d *terraform.ResourceDiff, meta interface{}) (*terraform.ResourceState, error) { r, ok := m.Mapping[s.Type] if !ok { return nil, fmt.Errorf("Unknown resource type: %s", s.Type) } if d.Destroy || d.RequiresNew() { if s.ID != "" { // Destroy the resource if it is created err := r.Destroy(s, meta) if err != nil { return s, err } s.ID = "" } // If we're only destroying, and not creating, then return now. // Otherwise, we continue so that we can create a new resource. if !d.RequiresNew() { return nil, nil } } var result *terraform.ResourceState var err error if s.ID == "" { result, err = r.Create(s, d, meta) } else { if r.Update == nil { return s, fmt.Errorf( "Resource type '%s' doesn't support update", s.Type) } result, err = r.Update(s, d, meta) } if result != nil { if result.Attributes == nil { result.Attributes = make(map[string]string) } result.Attributes["id"] = result.ID } return result, err }
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_r53_record_refresh( s *terraform.ResourceState, meta interface{}) (*terraform.ResourceState, error) { p := meta.(*ResourceProvider) conn := p.route53 zone := s.Attributes["zone_id"] lopts := &route53.ListOpts{ Name: s.Attributes["name"], Type: s.Attributes["type"], } resp, err := conn.ListResourceRecordSets(zone, lopts) if err != nil { return s, err } // Scan for a matching record found := false for _, record := range resp.Records { if route53.FQDN(record.Name) != route53.FQDN(lopts.Name) { continue } if strings.ToUpper(record.Type) != strings.ToUpper(lopts.Type) { continue } found = true resource_aws_r53_record_update_state(s, &record) break } if !found { s.ID = "" } return s, nil }
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 }