From 1dba855dafd79d7142a82bf55c17b90231fb3ff9 Mon Sep 17 00:00:00 2001 From: Joe Topjian Date: Wed, 1 Mar 2017 22:18:57 -0700 Subject: [PATCH] provider/openstack: openstack_compute_floatingip_associate_v2 resource (#12190) This commit adds the openstack_compute_floatingip_associate_v2 resource which specifically handles associating a floating IP address to an instance. This can be used instead of the existing floating_ip options in the openstack_compute_instance_v2 resource. --- ...ck_compute_floatingip_associate_v2_test.go | 28 ++ builtin/providers/openstack/provider.go | 65 ++-- ...enstack_compute_floatingip_associate_v2.go | 130 +++++++ ...ck_compute_floatingip_associate_v2_test.go | 324 ++++++++++++++++++ ...pute_floatingip_associate_v2.html.markdown | 98 ++++++ website/source/layouts/openstack.erb | 3 + 6 files changed, 616 insertions(+), 32 deletions(-) create mode 100644 builtin/providers/openstack/import_openstack_compute_floatingip_associate_v2_test.go create mode 100644 builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2.go create mode 100644 builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2_test.go create mode 100644 website/source/docs/providers/openstack/r/compute_floatingip_associate_v2.html.markdown diff --git a/builtin/providers/openstack/import_openstack_compute_floatingip_associate_v2_test.go b/builtin/providers/openstack/import_openstack_compute_floatingip_associate_v2_test.go new file mode 100644 index 000000000..d2bad3a00 --- /dev/null +++ b/builtin/providers/openstack/import_openstack_compute_floatingip_associate_v2_test.go @@ -0,0 +1,28 @@ +package openstack + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccOpenStackComputeV2FloatingIPAssociate_importBasic(t *testing.T) { + resourceName := "openstack_compute_floatingip_associate_v2.fip_1" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2FloatingIPAssociateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_basic, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/openstack/provider.go b/builtin/providers/openstack/provider.go index c4c44fa01..3ac9d870b 100644 --- a/builtin/providers/openstack/provider.go +++ b/builtin/providers/openstack/provider.go @@ -139,38 +139,39 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "openstack_blockstorage_volume_v1": resourceBlockStorageVolumeV1(), - "openstack_blockstorage_volume_v2": resourceBlockStorageVolumeV2(), - "openstack_blockstorage_volume_attach_v2": resourceBlockStorageVolumeAttachV2(), - "openstack_compute_instance_v2": resourceComputeInstanceV2(), - "openstack_compute_keypair_v2": resourceComputeKeypairV2(), - "openstack_compute_secgroup_v2": resourceComputeSecGroupV2(), - "openstack_compute_servergroup_v2": resourceComputeServerGroupV2(), - "openstack_compute_floatingip_v2": resourceComputeFloatingIPV2(), - "openstack_compute_volume_attach_v2": resourceComputeVolumeAttachV2(), - "openstack_fw_firewall_v1": resourceFWFirewallV1(), - "openstack_fw_policy_v1": resourceFWPolicyV1(), - "openstack_fw_rule_v1": resourceFWRuleV1(), - "openstack_images_image_v2": resourceImagesImageV2(), - "openstack_lb_member_v1": resourceLBMemberV1(), - "openstack_lb_monitor_v1": resourceLBMonitorV1(), - "openstack_lb_pool_v1": resourceLBPoolV1(), - "openstack_lb_vip_v1": resourceLBVipV1(), - "openstack_lb_loadbalancer_v2": resourceLoadBalancerV2(), - "openstack_lb_listener_v2": resourceListenerV2(), - "openstack_lb_pool_v2": resourcePoolV2(), - "openstack_lb_member_v2": resourceMemberV2(), - "openstack_lb_monitor_v2": resourceMonitorV2(), - "openstack_networking_network_v2": resourceNetworkingNetworkV2(), - "openstack_networking_subnet_v2": resourceNetworkingSubnetV2(), - "openstack_networking_floatingip_v2": resourceNetworkingFloatingIPV2(), - "openstack_networking_port_v2": resourceNetworkingPortV2(), - "openstack_networking_router_v2": resourceNetworkingRouterV2(), - "openstack_networking_router_interface_v2": resourceNetworkingRouterInterfaceV2(), - "openstack_networking_router_route_v2": resourceNetworkingRouterRouteV2(), - "openstack_networking_secgroup_v2": resourceNetworkingSecGroupV2(), - "openstack_networking_secgroup_rule_v2": resourceNetworkingSecGroupRuleV2(), - "openstack_objectstorage_container_v1": resourceObjectStorageContainerV1(), + "openstack_blockstorage_volume_v1": resourceBlockStorageVolumeV1(), + "openstack_blockstorage_volume_v2": resourceBlockStorageVolumeV2(), + "openstack_blockstorage_volume_attach_v2": resourceBlockStorageVolumeAttachV2(), + "openstack_compute_instance_v2": resourceComputeInstanceV2(), + "openstack_compute_keypair_v2": resourceComputeKeypairV2(), + "openstack_compute_secgroup_v2": resourceComputeSecGroupV2(), + "openstack_compute_servergroup_v2": resourceComputeServerGroupV2(), + "openstack_compute_floatingip_v2": resourceComputeFloatingIPV2(), + "openstack_compute_floatingip_associate_v2": resourceComputeFloatingIPAssociateV2(), + "openstack_compute_volume_attach_v2": resourceComputeVolumeAttachV2(), + "openstack_fw_firewall_v1": resourceFWFirewallV1(), + "openstack_fw_policy_v1": resourceFWPolicyV1(), + "openstack_fw_rule_v1": resourceFWRuleV1(), + "openstack_images_image_v2": resourceImagesImageV2(), + "openstack_lb_member_v1": resourceLBMemberV1(), + "openstack_lb_monitor_v1": resourceLBMonitorV1(), + "openstack_lb_pool_v1": resourceLBPoolV1(), + "openstack_lb_vip_v1": resourceLBVipV1(), + "openstack_lb_loadbalancer_v2": resourceLoadBalancerV2(), + "openstack_lb_listener_v2": resourceListenerV2(), + "openstack_lb_pool_v2": resourcePoolV2(), + "openstack_lb_member_v2": resourceMemberV2(), + "openstack_lb_monitor_v2": resourceMonitorV2(), + "openstack_networking_network_v2": resourceNetworkingNetworkV2(), + "openstack_networking_subnet_v2": resourceNetworkingSubnetV2(), + "openstack_networking_floatingip_v2": resourceNetworkingFloatingIPV2(), + "openstack_networking_port_v2": resourceNetworkingPortV2(), + "openstack_networking_router_v2": resourceNetworkingRouterV2(), + "openstack_networking_router_interface_v2": resourceNetworkingRouterInterfaceV2(), + "openstack_networking_router_route_v2": resourceNetworkingRouterRouteV2(), + "openstack_networking_secgroup_v2": resourceNetworkingSecGroupV2(), + "openstack_networking_secgroup_rule_v2": resourceNetworkingSecGroupRuleV2(), + "openstack_objectstorage_container_v1": resourceObjectStorageContainerV1(), }, ConfigureFunc: configureProvider, diff --git a/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2.go b/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2.go new file mode 100644 index 000000000..f3e0f5631 --- /dev/null +++ b/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2.go @@ -0,0 +1,130 @@ +package openstack + +import ( + "fmt" + "log" + "strings" + + "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceComputeFloatingIPAssociateV2() *schema.Resource { + return &schema.Resource{ + Create: resourceComputeFloatingIPAssociateV2Create, + Read: resourceComputeFloatingIPAssociateV2Read, + Delete: resourceComputeFloatingIPAssociateV2Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "region": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), + }, + "floating_ip": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "instance_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "fixed_ip": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceComputeFloatingIPAssociateV2Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + computeClient, err := config.computeV2Client(GetRegion(d)) + if err != nil { + return fmt.Errorf("Error creating OpenStack compute client: %s", err) + } + + floatingIP := d.Get("floating_ip").(string) + fixedIP := d.Get("fixed_ip").(string) + instanceId := d.Get("instance_id").(string) + + associateOpts := floatingips.AssociateOpts{ + FloatingIP: floatingIP, + FixedIP: fixedIP, + } + log.Printf("[DEBUG] Associate Options: %#v", associateOpts) + + err = floatingips.AssociateInstance(computeClient, instanceId, associateOpts).ExtractErr() + if err != nil { + return fmt.Errorf("Error associating Floating IP: %s", err) + } + + // There's an API call to get this information, but it has been + // deprecated. The Neutron API could be used, but I'm trying not + // to mix service APIs. Therefore, a faux ID will be used. + id := fmt.Sprintf("%s/%s/%s", floatingIP, instanceId, fixedIP) + d.SetId(id) + + // This API call is synchronous, so Create won't return until the IP + // is attached. No need to wait for a state. + + return resourceComputeFloatingIPAssociateV2Read(d, meta) +} + +func resourceComputeFloatingIPAssociateV2Read(d *schema.ResourceData, meta interface{}) error { + // Obtain relevant info from parsing the ID + floatingIP, instanceId, fixedIP, err := parseComputeFloatingIPAssociateId(d.Id()) + if err != nil { + return err + } + + d.Set("floating_ip", floatingIP) + d.Set("instance_id", instanceId) + d.Set("fixed_ip", fixedIP) + d.Set("region", GetRegion(d)) + + return nil +} + +func resourceComputeFloatingIPAssociateV2Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + computeClient, err := config.computeV2Client(GetRegion(d)) + if err != nil { + return fmt.Errorf("Error creating OpenStack compute client: %s", err) + } + + floatingIP := d.Get("floating_ip").(string) + instanceId := d.Get("instance_id").(string) + + disassociateOpts := floatingips.DisassociateOpts{ + FloatingIP: floatingIP, + } + log.Printf("[DEBUG] Disssociate Options: %#v", disassociateOpts) + + err = floatingips.DisassociateInstance(computeClient, instanceId, disassociateOpts).ExtractErr() + if err != nil { + return fmt.Errorf("Error disassociating floating IP: %s", err) + } + + return nil +} + +func parseComputeFloatingIPAssociateId(id string) (string, string, string, error) { + idParts := strings.Split(id, "/") + if len(idParts) < 3 { + return "", "", "", fmt.Errorf("Unable to determine floating ip association ID") + } + + floatingIP := idParts[0] + instanceId := idParts[1] + fixedIP := idParts[2] + + return floatingIP, instanceId, fixedIP, nil +} diff --git a/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2_test.go b/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2_test.go new file mode 100644 index 000000000..a9e7b3d4c --- /dev/null +++ b/builtin/providers/openstack/resource_openstack_compute_floatingip_associate_v2_test.go @@ -0,0 +1,324 @@ +package openstack + +import ( + "fmt" + "testing" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccComputeV2FloatingIPAssociate_basic(t *testing.T) { + var instance servers.Server + var fip floatingips.FloatingIP + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2FloatingIPAssociateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_1", &fip), + testAccCheckComputeV2FloatingIPAssociateAssociated(&fip, &instance, 1), + ), + }, + }, + }) +} + +func TestAccComputeV2FloatingIPAssociate_fixedIP(t *testing.T) { + var instance servers.Server + var fip floatingips.FloatingIP + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2FloatingIPAssociateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_fixedIP, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_1", &fip), + testAccCheckComputeV2FloatingIPAssociateAssociated(&fip, &instance, 1), + ), + }, + }, + }) +} + +func TestAccComputeV2FloatingIPAssociate_attachToFirstNetwork(t *testing.T) { + var instance servers.Server + var fip floatingips.FloatingIP + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2FloatingIPAssociateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_attachToFirstNetwork, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_1", &fip), + testAccCheckComputeV2FloatingIPAssociateAssociated(&fip, &instance, 1), + ), + }, + }, + }) +} + +func TestAccComputeV2FloatingIPAssociate_attachToSecondNetwork(t *testing.T) { + var instance servers.Server + var fip floatingips.FloatingIP + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2FloatingIPAssociateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_attachToSecondNetwork, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_1", &fip), + testAccCheckComputeV2FloatingIPAssociateAssociated(&fip, &instance, 2), + ), + }, + }, + }) +} + +func TestAccComputeV2FloatingIPAssociate_attachNew(t *testing.T) { + var instance servers.Server + var fip_1 floatingips.FloatingIP + var fip_2 floatingips.FloatingIP + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2FloatingIPAssociateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_attachNew_1, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_1", &fip_1), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_2", &fip_2), + testAccCheckComputeV2FloatingIPAssociateAssociated(&fip_1, &instance, 1), + ), + }, + resource.TestStep{ + Config: testAccComputeV2FloatingIPAssociate_attachNew_2, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists("openstack_compute_instance_v2.instance_1", &instance), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_1", &fip_1), + testAccCheckNetworkingV2FloatingIPExists("openstack_networking_floatingip_v2.fip_2", &fip_2), + testAccCheckComputeV2FloatingIPAssociateAssociated(&fip_2, &instance, 1), + ), + }, + }, + }) +} + +func testAccCheckComputeV2FloatingIPAssociateDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + computeClient, err := config.computeV2Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating OpenStack compute client: %s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "openstack_compute_floatingip_associate_v2" { + continue + } + + floatingIP, instanceId, _, err := parseComputeFloatingIPAssociateId(rs.Primary.ID) + if err != nil { + return err + } + + instance, err := servers.Get(computeClient, instanceId).Extract() + if err != nil { + // If the error is a 404, then the instance does not exist, + // and therefore the floating IP cannot be associated to it. + if _, ok := err.(gophercloud.ErrDefault404); ok { + return nil + } + return err + } + + // But if the instance still exists, then walk through its known addresses + // and see if there's a floating IP. + for _, networkAddresses := range instance.Addresses { + for _, element := range networkAddresses.([]interface{}) { + address := element.(map[string]interface{}) + if address["OS-EXT-IPS:type"] == "floating" { + return fmt.Errorf("Floating IP %s is still attached to instance %s", floatingIP, instanceId) + } + } + } + } + + return nil +} + +func testAccCheckComputeV2FloatingIPAssociateAssociated( + fip *floatingips.FloatingIP, instance *servers.Server, n int) resource.TestCheckFunc { + return func(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + computeClient, err := config.computeV2Client(OS_REGION_NAME) + + newInstance, err := servers.Get(computeClient, instance.ID).Extract() + if err != nil { + return err + } + + // Walk through the instance's addresses and find the match + i := 0 + for _, networkAddresses := range newInstance.Addresses { + i += 1 + if i != n { + continue + } + for _, element := range networkAddresses.([]interface{}) { + address := element.(map[string]interface{}) + if address["OS-EXT-IPS:type"] == "floating" && address["addr"] == fip.FloatingIP { + return nil + } + } + } + return fmt.Errorf("Floating IP %s was not attached to instance %s", fip.FloatingIP, instance.ID) + } +} + +const testAccComputeV2FloatingIPAssociate_basic = ` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] +} + +resource "openstack_networking_floatingip_v2" "fip_1" { +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" +} +` + +const testAccComputeV2FloatingIPAssociate_fixedIP = ` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] +} + +resource "openstack_networking_floatingip_v2" "fip_1" { +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" + fixed_ip = "${openstack_compute_instance_v2.instance_1.access_ip_v4}" +} +` + +var testAccComputeV2FloatingIPAssociate_attachToFirstNetwork = fmt.Sprintf(` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] + + network { + uuid = "%s" + } +} + +resource "openstack_networking_floatingip_v2" "fip_1" { +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" + fixed_ip = "${openstack_compute_instance_v2.instance_1.network.0.fixed_ip_v4}" +} +`, OS_NETWORK_ID) + +var testAccComputeV2FloatingIPAssociate_attachToSecondNetwork = fmt.Sprintf(` +resource "openstack_networking_network_v2" "network_1" { + name = "network_1" +} + +resource "openstack_networking_subnet_v2" "subnet_1" { + name = "subnet_1" + network_id = "${openstack_networking_network_v2.network_1.id}" + cidr = "192.168.1.0/24" + ip_version = 4 + enable_dhcp = true + no_gateway = true +} + +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] + + network { + uuid = "${openstack_networking_network_v2.network_1.id}" + } + + network { + uuid = "%s" + } +} + +resource "openstack_networking_floatingip_v2" "fip_1" { +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" + fixed_ip = "${openstack_compute_instance_v2.instance_1.network.1.fixed_ip_v4}" +} +`, OS_NETWORK_ID) + +const testAccComputeV2FloatingIPAssociate_attachNew_1 = ` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] +} + +resource "openstack_networking_floatingip_v2" "fip_1" { +} + +resource "openstack_networking_floatingip_v2" "fip_2" { +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" +} +` + +const testAccComputeV2FloatingIPAssociate_attachNew_2 = ` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] +} + +resource "openstack_networking_floatingip_v2" "fip_1" { +} + +resource "openstack_networking_floatingip_v2" "fip_2" { +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_2.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" +} +` diff --git a/website/source/docs/providers/openstack/r/compute_floatingip_associate_v2.html.markdown b/website/source/docs/providers/openstack/r/compute_floatingip_associate_v2.html.markdown new file mode 100644 index 000000000..d729e36b5 --- /dev/null +++ b/website/source/docs/providers/openstack/r/compute_floatingip_associate_v2.html.markdown @@ -0,0 +1,98 @@ +--- +layout: "openstack" +page_title: "OpenStack: openstack_compute_floatingip_associate_v2" +sidebar_current: "docs-openstack-resource-compute-floatingip-associate-v2" +description: |- + Associate a floating IP to an instance +--- + +# openstack\_compute\_floatingip_associate_v2 + +Associate a floating IP to an instance. This can be used instead of the +`floating_ip` options in `openstack_compute_instance_v2`. + +## Example Usage + +### Automatically detect the correct network + +``` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + image_id = "ad091b52-742f-469e-8f3c-fd81cadf0743" + flavor_id = 3 + key_pair = "my_key_pair_name" + security_groups = ["default"] +} + +resource "openstack_networking_floatingip_v2" "fip_1" { + pool = "my_pool" +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" +} +``` + +### Explicitly set the network to attach to + +``` +resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + image_id = "ad091b52-742f-469e-8f3c-fd81cadf0743" + flavor_id = 3 + key_pair = "my_key_pair_name" + security_groups = ["default"] + + network { + name = "my_network" + } + + network { + name = "default" + } +} + +resource "openstack_networking_floatingip_v2" "fip_1" { + pool = "my_pool" +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.instance_1.id}" + fixed_ip = "${openstack_compute_instance_v2.instance_1.network.1.fixed_ip_v4}" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Required) The region in which to obtain the V2 Compute client. + Keypairs are associated with accounts, but a Compute client is needed to + create one. If omitted, the `OS_REGION_NAME` environment variable is used. + Changing this creates a new floatingip_associate. + +* `floating_ip` - (Required) The floating IP to associate. + +* `instance_id` - (Required) The instance to associte the floating IP with. + +* `fixed_ip` - (Optional) The specific IP address to direct traffic to. + +## Attributes Reference + +The following attributes are exported: + +* `region` - See Argument Reference above. +* `floating_ip` - See Argument Reference above. +* `instance_id` - See Argument Reference above. +* `fixed_ip` - See Argument Reference above. + +## Import + +This resource can be imported by specifying all three arguments, separated +by a forward slash: + +``` +$ terraform import openstack_compute_floatingip_associate_v2.fip_1 // +``` diff --git a/website/source/layouts/openstack.erb b/website/source/layouts/openstack.erb index 4f0581349..9d784e74c 100644 --- a/website/source/layouts/openstack.erb +++ b/website/source/layouts/openstack.erb @@ -40,6 +40,9 @@ > openstack_compute_floatingip_v2 + > + openstack_compute_floatingip_associate_v2 + > openstack_compute_instance_v2