func resourceDigitalOceanDropletRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*godo.Client) id, err := strconv.Atoi(d.Id()) if err != nil { return fmt.Errorf("invalid droplet id: %v", err) } // Retrieve the droplet properties for updating the state droplet, resp, err := client.Droplets.Get(id) if err != nil { // check if the droplet no longer exists. if resp.StatusCode == 404 { log.Printf("[WARN] DigitalOcean Droplet (%s) not found", d.Id()) d.SetId("") return nil } return fmt.Errorf("Error retrieving droplet: %s", err) } if droplet.Image.Slug != "" { d.Set("image", droplet.Image.Slug) } else { d.Set("image", droplet.Image.ID) } d.Set("name", droplet.Name) d.Set("region", droplet.Region.Slug) d.Set("size", droplet.Size.Slug) d.Set("status", droplet.Status) d.Set("locked", strconv.FormatBool(droplet.Locked)) if publicIPv6 := findIPv6AddrByType(droplet, "public"); publicIPv6 != "" { d.Set("ipv6", true) d.Set("ipv6_address", publicIPv6) d.Set("ipv6_address_private", findIPv6AddrByType(droplet, "private")) } d.Set("ipv4_address", findIPv4AddrByType(droplet, "public")) if privateIPv4 := findIPv4AddrByType(droplet, "private"); privateIPv4 != "" { d.Set("private_networking", true) d.Set("ipv4_address_private", privateIPv4) } // Initialize the connection info d.SetConnInfo(map[string]string{ "type": "ssh", "host": findIPv4AddrByType(droplet, "public"), }) return nil }
func readInstance(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn resp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ InstanceIds: []*string{aws.String(d.Get("spot_instance_id").(string))}, }) if err != nil { // If the instance was not found, return nil so that we can show // that the instance is gone. if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidInstanceID.NotFound" { return fmt.Errorf("no instance found") } // Some other error, report it return err } // If nothing was found, then return no state if len(resp.Reservations) == 0 { return fmt.Errorf("no instances found") } instance := resp.Reservations[0].Instances[0] // Set these fields for connection information if instance != nil { d.Set("public_dns", instance.PublicDnsName) d.Set("public_ip", instance.PublicIpAddress) d.Set("private_dns", instance.PrivateDnsName) d.Set("private_ip", instance.PrivateIpAddress) // set connection information if instance.PublicIpAddress != nil { d.SetConnInfo(map[string]string{ "type": "ssh", "host": *instance.PublicIpAddress, }) } else if instance.PrivateIpAddress != nil { d.SetConnInfo(map[string]string{ "type": "ssh", "host": *instance.PrivateIpAddress, }) } } return nil }
func resourceAzureInstanceRead(d *schema.ResourceData, meta interface{}) error { azureClient := meta.(*Client) hostedServiceClient := azureClient.hostedServiceClient vmClient := azureClient.vmClient name := d.Get("name").(string) // check if the instance belongs to an independent hosted service // or it had one created for it. var hostedServiceName string if serviceName, ok := d.GetOk("hosted_service_name"); ok { // if independent; use that hosted service name: hostedServiceName = serviceName.(string) } else { // else; suppose it's the instance's name: hostedServiceName = name } log.Printf("[DEBUG] Retrieving Cloud Service for instance: %s", name) cs, err := hostedServiceClient.GetHostedService(hostedServiceName) if err != nil { return fmt.Errorf("Error retrieving Cloud Service of instance %s (%q): %s", name, hostedServiceName, err) } d.Set("reverse_dns", cs.ReverseDNSFqdn) d.Set("location", cs.Location) log.Printf("[DEBUG] Retrieving instance: %s", name) dpmt, err := vmClient.GetDeployment(hostedServiceName, name) if err != nil { if management.IsResourceNotFoundError(err) { d.SetId("") return nil } return fmt.Errorf("Error retrieving instance %s: %s", name, err) } if len(dpmt.RoleList) != 1 { return fmt.Errorf( "Instance %s has an unexpected number of roles: %d", name, len(dpmt.RoleList)) } d.Set("size", dpmt.RoleList[0].RoleSize) if len(dpmt.RoleInstanceList) != 1 { return fmt.Errorf( "Instance %s has an unexpected number of role instances: %d", name, len(dpmt.RoleInstanceList)) } d.Set("ip_address", dpmt.RoleInstanceList[0].IPAddress) if len(dpmt.RoleInstanceList[0].InstanceEndpoints) > 0 { d.Set("vip_address", dpmt.RoleInstanceList[0].InstanceEndpoints[0].Vip) } // Find the network configuration set for _, c := range dpmt.RoleList[0].ConfigurationSets { if c.ConfigurationSetType == virtualmachine.ConfigurationSetTypeNetwork { // Create a new set to hold all configured endpoints endpoints := &schema.Set{ F: resourceAzureEndpointHash, } // Loop through all endpoints for _, ep := range c.InputEndpoints { endpoint := map[string]interface{}{} // Update the values endpoint["name"] = ep.Name endpoint["protocol"] = string(ep.Protocol) endpoint["public_port"] = ep.Port endpoint["private_port"] = ep.LocalPort endpoints.Add(endpoint) } d.Set("endpoint", endpoints) // Update the subnet switch len(c.SubnetNames) { case 1: d.Set("subnet", c.SubnetNames[0]) case 0: d.Set("subnet", "") default: return fmt.Errorf( "Instance %s has an unexpected number of associated subnets %d", name, len(dpmt.RoleInstanceList)) } // Update the security group d.Set("security_group", c.NetworkSecurityGroup) } } connType := "ssh" if dpmt.RoleList[0].OSVirtualHardDisk.OS == windows { connType = "winrm" } // Set the connection info for any configured provisioners d.SetConnInfo(map[string]string{ "type": connType, "host": dpmt.VirtualIPs[0].Address, "user": d.Get("username").(string), "password": d.Get("password").(string), }) return nil }
func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn instanceOpts, err := buildAwsInstanceOpts(d, meta) if err != nil { return err } // Build the creation struct runOpts := &ec2.RunInstancesInput{ BlockDeviceMappings: instanceOpts.BlockDeviceMappings, DisableApiTermination: instanceOpts.DisableAPITermination, EbsOptimized: instanceOpts.EBSOptimized, Monitoring: instanceOpts.Monitoring, IamInstanceProfile: instanceOpts.IAMInstanceProfile, ImageId: instanceOpts.ImageID, InstanceInitiatedShutdownBehavior: instanceOpts.InstanceInitiatedShutdownBehavior, InstanceType: instanceOpts.InstanceType, KeyName: instanceOpts.KeyName, MaxCount: aws.Int64(int64(1)), MinCount: aws.Int64(int64(1)), NetworkInterfaces: instanceOpts.NetworkInterfaces, Placement: instanceOpts.Placement, PrivateIpAddress: instanceOpts.PrivateIPAddress, SecurityGroupIds: instanceOpts.SecurityGroupIDs, SecurityGroups: instanceOpts.SecurityGroups, SubnetId: instanceOpts.SubnetID, UserData: instanceOpts.UserData64, } // Create the instance log.Printf("[DEBUG] Run configuration: %s", runOpts) var runResp *ec2.Reservation for i := 0; i < 5; i++ { runResp, err = conn.RunInstances(runOpts) if awsErr, ok := err.(awserr.Error); ok { // 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 if awsErr.Code() == "InvalidParameterValue" && strings.Contains(awsErr.Message(), "Invalid IAM Instance Profile") { log.Printf("[DEBUG] Invalid IAM Instance Profile referenced, retrying...") time.Sleep(2 * time.Second) continue } // Warn if the AWS Error involves group ids, to help identify situation // where a user uses group ids in security_groups for the Default VPC. // See https://github.com/hashicorp/terraform/issues/3798 if awsErr.Code() == "InvalidParameterValue" && strings.Contains(awsErr.Message(), "groupId is invalid") { return fmt.Errorf("Error launching instance, possible mismatch of Security Group IDs and Names. See AWS Instance docs here: %s.\n\n\tAWS Error: %s", "https://terraform.io/docs/providers/aws/r/instance.html", awsErr.Message()) } } break } if err != nil { return fmt.Errorf("Error launching source instance: %s", err) } if runResp == nil || len(runResp.Instances) == 0 { return fmt.Errorf("Error launching source instance: no instances returned in response") } instance := runResp.Instances[0] log.Printf("[INFO] Instance ID: %s", *instance.InstanceId) // Store the resulting ID so we can look this up later d.SetId(*instance.InstanceId) // Wait for the instance to become running so we can get some attributes // that aren't available until later. log.Printf( "[DEBUG] Waiting for instance (%s) to become running", *instance.InstanceId) stateConf := &resource.StateChangeConf{ Pending: []string{"pending"}, Target: "running", Refresh: InstanceStateRefreshFunc(conn, *instance.InstanceId), Timeout: 10 * time.Minute, Delay: 10 * time.Second, MinTimeout: 3 * time.Second, } instanceRaw, err := stateConf.WaitForState() if err != nil { return fmt.Errorf( "Error waiting for instance (%s) to become ready: %s", *instance.InstanceId, err) } instance = instanceRaw.(*ec2.Instance) // Initialize the connection info if instance.PublicIpAddress != nil { d.SetConnInfo(map[string]string{ "type": "ssh", "host": *instance.PublicIpAddress, }) } else if instance.PrivateIpAddress != nil { d.SetConnInfo(map[string]string{ "type": "ssh", "host": *instance.PrivateIpAddress, }) } // Update if we need to return resourceAwsInstanceUpdate(d, meta) }
func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{}) error { cs := meta.(*cloudstack.CloudStackClient) // Retrieve the service_offering ID serviceofferingid, e := retrieveID(cs, "service_offering", d.Get("service_offering").(string)) if e != nil { return e.Error() } // Retrieve the zone ID zoneid, e := retrieveID(cs, "zone", d.Get("zone").(string)) if e != nil { return e.Error() } // Retrieve the zone object zone, _, err := cs.Zone.GetZoneByID(zoneid) if err != nil { return err } // Retrieve the template ID templateid, e := retrieveTemplateID(cs, zone.Id, d.Get("template").(string)) if e != nil { return e.Error() } // Create a new parameter struct p := cs.VirtualMachine.NewDeployVirtualMachineParams(serviceofferingid, templateid, zone.Id) // Set the name name := d.Get("name").(string) p.SetName(name) // Set the display name if displayname, ok := d.GetOk("display_name"); ok { p.SetDisplayname(displayname.(string)) } else { p.SetDisplayname(name) } if zone.Networktype == "Advanced" { // Retrieve the network ID networkid, e := retrieveID(cs, "network", d.Get("network").(string)) if e != nil { return e.Error() } // Set the default network ID p.SetNetworkids([]string{networkid}) } // If there is a ipaddres supplied, add it to the parameter struct if ipaddres, ok := d.GetOk("ipaddress"); ok { p.SetIpaddress(ipaddres.(string)) } // If there is a project supplied, we retrieve and set the project id if project, ok := d.GetOk("project"); ok { // Retrieve the project ID projectid, e := retrieveID(cs, "project", project.(string)) if e != nil { return e.Error() } // Set the default project ID p.SetProjectid(projectid) } // If a keypair is supplied, add it to the parameter struct if keypair, ok := d.GetOk("keypair"); ok { p.SetKeypair(keypair.(string)) } // If the user data contains any info, it needs to be base64 encoded and // added to the parameter struct if userData, ok := d.GetOk("user_data"); ok { ud := base64.StdEncoding.EncodeToString([]byte(userData.(string))) // deployVirtualMachine uses POST by default, so max userdata is 32K maxUD := 32768 if cs.HTTPGETOnly { // deployVirtualMachine using GET instead, so max userdata is 2K maxUD = 2048 } if len(ud) > maxUD { return fmt.Errorf( "The supplied user_data contains %d bytes after encoding, "+ "this exeeds the limit of %d bytes", len(ud), maxUD) } p.SetUserdata(ud) } // Create the new instance r, err := cs.VirtualMachine.DeployVirtualMachine(p) if err != nil { return fmt.Errorf("Error creating the new instance %s: %s", name, err) } d.SetId(r.Id) // Set the connection info for any configured provisioners d.SetConnInfo(map[string]string{ "host": r.Nic[0].Ipaddress, "password": r.Password, }) return resourceCloudStackInstanceRead(d, meta) }
func resourceComputeInstanceV2Read(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) computeClient, err := config.computeV2Client(d.Get("region").(string)) if err != nil { return fmt.Errorf("Error creating OpenStack compute client: %s", err) } server, err := servers.Get(computeClient, d.Id()).Extract() if err != nil { return CheckDeleted(d, err, "server") } log.Printf("[DEBUG] Retreived Server %s: %+v", d.Id(), server) d.Set("name", server.Name) // begin reading the network configuration d.Set("access_ip_v4", server.AccessIPv4) d.Set("access_ip_v6", server.AccessIPv6) hostv4 := server.AccessIPv4 hostv6 := server.AccessIPv6 networkDetails, err := resourceInstanceNetworks(computeClient, d) addresses := resourceInstanceAddresses(server.Addresses) if err != nil { return err } // if there are no networkDetails, make networks at least a length of 1 networkLength := 1 if len(networkDetails) > 0 { networkLength = len(networkDetails) } networks := make([]map[string]interface{}, networkLength) // Loop through all networks and addresses, // merge relevant address details. if len(networkDetails) == 0 { for netName, n := range addresses { if floatingIP, ok := n["floating_ip"]; ok { hostv4 = floatingIP.(string) } else { if hostv4 == "" && n["fixed_ip_v4"] != nil { hostv4 = n["fixed_ip_v4"].(string) } } if hostv6 == "" && n["fixed_ip_v6"] != nil { hostv6 = n["fixed_ip_v6"].(string) } networks[0] = map[string]interface{}{ "name": netName, "fixed_ip_v4": n["fixed_ip_v4"], "fixed_ip_v6": n["fixed_ip_v6"], "mac": n["mac"], } } } else { for i, net := range networkDetails { n := addresses[net["name"].(string)] if floatingIP, ok := n["floating_ip"]; ok { hostv4 = floatingIP.(string) } else { if hostv4 == "" && n["fixed_ip_v4"] != nil { hostv4 = n["fixed_ip_v4"].(string) } } if hostv6 == "" && n["fixed_ip_v6"] != nil { hostv6 = n["fixed_ip_v6"].(string) } networks[i] = map[string]interface{}{ "uuid": networkDetails[i]["uuid"], "name": networkDetails[i]["name"], "port": networkDetails[i]["port"], "fixed_ip_v4": n["fixed_ip_v4"], "fixed_ip_v6": n["fixed_ip_v6"], "mac": n["mac"], } } } log.Printf("[DEBUG] new networks: %+v", networks) d.Set("network", networks) d.Set("access_ip_v4", hostv4) d.Set("access_ip_v6", hostv6) log.Printf("hostv4: %s", hostv4) log.Printf("hostv6: %s", hostv6) // prefer the v6 address if no v4 address exists. preferredv := "" if hostv4 != "" { preferredv = hostv4 } else if hostv6 != "" { preferredv = hostv6 } if preferredv != "" { // Initialize the connection info d.SetConnInfo(map[string]string{ "type": "ssh", "host": preferredv, }) } // end network configuration d.Set("metadata", server.Metadata) secGrpNames := []string{} for _, sg := range server.SecurityGroups { secGrpNames = append(secGrpNames, sg["name"].(string)) } d.Set("security_groups", secGrpNames) flavorId, ok := server.Flavor["id"].(string) if !ok { return fmt.Errorf("Error setting OpenStack server's flavor: %v", server.Flavor) } d.Set("flavor_id", flavorId) flavor, err := flavors.Get(computeClient, flavorId).Extract() if err != nil { return err } d.Set("flavor_name", flavor.Name) // Set the instance's image information appropriately if err := setImageInformation(computeClient, server, d); err != nil { return err } // volume attachments if err := getVolumeAttachments(computeClient, d); err != nil { return err } return nil }
func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*packngo.Client) device, _, err := client.Devices.Get(d.Id()) if err != nil { err = friendlyError(err) // If the device somehow already destroyed, mark as succesfully gone. if isNotFound(err) { d.SetId("") return nil } return err } d.Set("name", device.Hostname) d.Set("plan", device.Plan.Slug) d.Set("facility", device.Facility.Code) d.Set("operating_system", device.OS.Slug) d.Set("state", device.State) d.Set("billing_cycle", device.BillingCycle) d.Set("locked", device.Locked) d.Set("created", device.Created) d.Set("updated", device.Updated) tags := make([]string, 0, len(device.Tags)) for _, tag := range device.Tags { tags = append(tags, tag) } d.Set("tags", tags) var ( host string networks = make([]map[string]interface{}, 0, 1) ) for _, ip := range device.Network { network := map[string]interface{}{ "address": ip.Address, "gateway": ip.Gateway, "family": ip.Family, "cidr": ip.Cidr, "public": ip.Public, } networks = append(networks, network) if ip.Family == 4 && ip.Public == true { host = ip.Address } } d.Set("network", networks) if host != "" { d.SetConnInfo(map[string]string{ "type": "ssh", "host": host, }) } return nil }
func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) id := d.Id() instance, err := getInstance(config, d) if err != nil { if strings.Contains(err.Error(), "no longer exists") { log.Printf("[WARN] Google Compute Instance (%s) not found", id) return nil } return err } // Synch metadata md := instance.Metadata _md := MetadataFormatSchema(d.Get("metadata").(map[string]interface{}), md) delete(_md, "startup-script") if script, scriptExists := d.GetOk("metadata_startup_script"); scriptExists { d.Set("metadata_startup_script", script) } if err = d.Set("metadata", _md); err != nil { return fmt.Errorf("Error setting metadata: %s", err) } d.Set("can_ip_forward", instance.CanIpForward) // Set the service accounts serviceAccounts := make([]map[string]interface{}, 0, 1) for _, serviceAccount := range instance.ServiceAccounts { scopes := make([]interface{}, len(serviceAccount.Scopes)) for i, scope := range serviceAccount.Scopes { scopes[i] = scope } serviceAccounts = append(serviceAccounts, map[string]interface{}{ "email": serviceAccount.Email, "scopes": schema.NewSet(stringScopeHashcode, scopes), }) } d.Set("service_account", serviceAccounts) networksCount := d.Get("network.#").(int) networkInterfacesCount := d.Get("network_interface.#").(int) if networksCount > 0 && networkInterfacesCount > 0 { return fmt.Errorf("Error: cannot define both networks and network_interfaces.") } if networksCount == 0 && networkInterfacesCount == 0 { return fmt.Errorf("Error: Must define at least one network_interface.") } // Set the networks // Use the first external IP found for the default connection info. externalIP := "" internalIP := "" networks := make([]map[string]interface{}, 0, 1) if networksCount > 0 { // TODO: Remove this when realizing deprecation of .network for i, iface := range instance.NetworkInterfaces { var natIP string for _, config := range iface.AccessConfigs { if config.Type == "ONE_TO_ONE_NAT" { natIP = config.NatIP break } } if externalIP == "" && natIP != "" { externalIP = natIP } network := make(map[string]interface{}) network["name"] = iface.Name network["external_address"] = natIP network["internal_address"] = iface.NetworkIP network["source"] = d.Get(fmt.Sprintf("network.%d.source", i)) networks = append(networks, network) } } d.Set("network", networks) networkInterfaces := make([]map[string]interface{}, 0, 1) if networkInterfacesCount > 0 { for i, iface := range instance.NetworkInterfaces { // The first non-empty ip is left in natIP var natIP string accessConfigs := make( []map[string]interface{}, 0, len(iface.AccessConfigs)) for j, config := range iface.AccessConfigs { accessConfigs = append(accessConfigs, map[string]interface{}{ "nat_ip": d.Get(fmt.Sprintf("network_interface.%d.access_config.%d.nat_ip", i, j)), "assigned_nat_ip": config.NatIP, }) if natIP == "" { natIP = config.NatIP } } if externalIP == "" { externalIP = natIP } if internalIP == "" { internalIP = iface.NetworkIP } networkInterfaces = append(networkInterfaces, map[string]interface{}{ "name": iface.Name, "address": iface.NetworkIP, "network": d.Get(fmt.Sprintf("network_interface.%d.network", i)), "access_config": accessConfigs, }) } } d.Set("network_interface", networkInterfaces) // Fall back on internal ip if there is no external ip. This makes sense in the situation where // terraform is being used on a cloud instance and can therefore access the instances it creates // via their internal ips. sshIP := externalIP if sshIP == "" { sshIP = internalIP } // Initialize the connection info d.SetConnInfo(map[string]string{ "type": "ssh", "host": sshIP, }) // Set the metadata fingerprint if there is one. if instance.Metadata != nil { d.Set("metadata_fingerprint", instance.Metadata.Fingerprint) } // Set the tags fingerprint if there is one. if instance.Tags != nil { d.Set("tags_fingerprint", instance.Tags.Fingerprint) } d.Set("self_link", instance.SelfLink) d.SetId(instance.Name) return nil }