provider/alicloud: Fix allocate public ip error (#13267) (#13268)

Wait for instance to be in STOPPED or RUNNING state before invoking
AllocatePublicIP API.

* provider/alicloud: Wait for instance state before allocate public ip

* provider/alicloud: Fix test `TestAccAlicloudInstance_associatePublicIP`

* provider/alicloud: Update alicloud_instance document

Fixes: #13267
This commit is contained in:
Kent Wang 2017-04-17 06:52:39 +08:00 committed by Paul Stack
parent 7480454e31
commit 8927ad5dce
3 changed files with 28 additions and 15 deletions

View File

@ -194,6 +194,12 @@ func resourceAliyunInstanceCreate(d *schema.ResourceData, meta interface{}) erro
//d.Set("system_disk_category", d.Get("system_disk_category")) //d.Set("system_disk_category", d.Get("system_disk_category"))
//d.Set("system_disk_size", d.Get("system_disk_size")) //d.Set("system_disk_size", d.Get("system_disk_size"))
// after instance created, its status is pending,
// so we need to wait it become to stopped and then start it
if err := conn.WaitForInstance(d.Id(), ecs.Stopped, defaultTimeout); err != nil {
log.Printf("[DEBUG] WaitForInstance %s got error: %#v", ecs.Stopped, err)
}
if d.Get("allocate_public_ip").(bool) { if d.Get("allocate_public_ip").(bool) {
_, err := conn.AllocatePublicIpAddress(d.Id()) _, err := conn.AllocatePublicIpAddress(d.Id())
if err != nil { if err != nil {
@ -201,12 +207,6 @@ func resourceAliyunInstanceCreate(d *schema.ResourceData, meta interface{}) erro
} }
} }
// after instance created, its status is pending,
// so we need to wait it become to stopped and then start it
if err := conn.WaitForInstance(d.Id(), ecs.Stopped, defaultTimeout); err != nil {
log.Printf("[DEBUG] WaitForInstance %s got error: %#v", ecs.Stopped, err)
}
if err := conn.StartInstance(d.Id()); err != nil { if err := conn.StartInstance(d.Id()); err != nil {
return fmt.Errorf("Start instance got error: %#v", err) return fmt.Errorf("Start instance got error: %#v", err)
} }
@ -253,6 +253,11 @@ func resourceAliyunRunInstance(d *schema.ResourceData, meta interface{}) error {
d.Set("system_disk_category", d.Get("system_disk_category")) d.Set("system_disk_category", d.Get("system_disk_category"))
d.Set("system_disk_size", d.Get("system_disk_size")) d.Set("system_disk_size", d.Get("system_disk_size"))
// after instance created, its status change from pending, starting to running
if err := conn.WaitForInstanceAsyn(d.Id(), ecs.Running, defaultTimeout); err != nil {
log.Printf("[DEBUG] WaitForInstance %s got error: %#v", ecs.Running, err)
}
if d.Get("allocate_public_ip").(bool) { if d.Get("allocate_public_ip").(bool) {
_, err := conn.AllocatePublicIpAddress(d.Id()) _, err := conn.AllocatePublicIpAddress(d.Id())
if err != nil { if err != nil {
@ -260,11 +265,6 @@ func resourceAliyunRunInstance(d *schema.ResourceData, meta interface{}) error {
} }
} }
// after instance created, its status change from pending, starting to running
if err := conn.WaitForInstanceAsyn(d.Id(), ecs.Running, defaultTimeout); err != nil {
log.Printf("[DEBUG] WaitForInstance %s got error: %#v", ecs.Running, err)
}
return resourceAliyunInstanceUpdate(d, meta) return resourceAliyunInstanceUpdate(d, meta)
} }

View File

@ -4,12 +4,13 @@ import (
"fmt" "fmt"
"testing" "testing"
"log"
"github.com/denverdino/aliyungo/common" "github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs" "github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
"log"
) )
func TestAccAlicloudInstance_basic(t *testing.T) { func TestAccAlicloudInstance_basic(t *testing.T) {
@ -456,6 +457,17 @@ func TestAccAlicloudInstance_associatePublicIP(t *testing.T) {
} }
} }
testCheckPublicIP := func() resource.TestCheckFunc {
return func(*terraform.State) error {
publicIP := instance.PublicIpAddress.IpAddress[0]
if publicIP == "" {
return fmt.Errorf("can't get public IP")
}
return nil
}
}
resource.Test(t, resource.TestCase{ resource.Test(t, resource.TestCase{
PreCheck: func() { PreCheck: func() {
testAccPreCheck(t) testAccPreCheck(t)
@ -469,6 +481,7 @@ func TestAccAlicloudInstance_associatePublicIP(t *testing.T) {
Check: resource.ComposeTestCheckFunc( Check: resource.ComposeTestCheckFunc(
testAccCheckInstanceExists("alicloud_instance.foo", &instance), testAccCheckInstanceExists("alicloud_instance.foo", &instance),
testCheckPrivateIP(), testCheckPrivateIP(),
testCheckPublicIP(),
), ),
}, },
}, },

View File

@ -6,7 +6,7 @@ description: |-
Provides a ECS instance resource. Provides a ECS instance resource.
--- ---
# alicloud_ecs # alicloud\_instance
Provides a ECS instance resource. Provides a ECS instance resource.
@ -22,7 +22,7 @@ resource "alicloud_security_group" "classic" {
resource "alicloud_instance" "classic" { resource "alicloud_instance" "classic" {
# cn-beijing # cn-beijing
availability_zone = "cn-beijing-b" availability_zone = "cn-beijing-b"
security_group_id = "${alicloud_security_group.classic.id}" security_groups = ["${alicloud_security_group.classic.*.id}"]
allocate_public_ip = "true" allocate_public_ip = "true"
@ -57,7 +57,7 @@ The following arguments are supported:
* `image_id` - (Required) The Image to use for the instance. * `image_id` - (Required) The Image to use for the instance.
* `instance_type` - (Required) The type of instance to start. * `instance_type` - (Required) The type of instance to start.
* `io_optimized` - (Required) Valid values are `none`, `optimized`, If `optimized`, the launched ECS instance will be I/O optimized. * `io_optimized` - (Required) Valid values are `none`, `optimized`, If `optimized`, the launched ECS instance will be I/O optimized.
* `security_group_ids` - (Optional) A list of security group ids to associate with. * `security_groups` - (Optional) A list of security group ids to associate with.
* `availability_zone` - (Optional) The Zone to start the instance in. * `availability_zone` - (Optional) The Zone to start the instance in.
* `instance_name` - (Optional) The name of the ECS. This instance_name can have a string of 2 to 128 characters, must contain only alphanumeric characters or hyphens, such as "-",".","\_", and must not begin or end with a hyphen, and must not begin with http:// or https://. If not specified, * `instance_name` - (Optional) The name of the ECS. This instance_name can have a string of 2 to 128 characters, must contain only alphanumeric characters or hyphens, such as "-",".","\_", and must not begin or end with a hyphen, and must not begin with http:// or https://. If not specified,
Terraform will autogenerate a default name is `ECS-Instance`. Terraform will autogenerate a default name is `ECS-Instance`.