provider/alicloud: Add new resource ESS, including scalinggroup scalingconfiguration scalingrule and schedule (#13731)

* add docs

* add new resource ess

* add examples

* update aliyun go

* merge master

* fix ci
This commit is contained in:
demonwy 2017-04-18 20:18:57 +08:00 committed by Paul Stack
parent 16c0594c47
commit 69ec7e12ac
80 changed files with 5475 additions and 303 deletions

View File

@ -17,38 +17,39 @@ const (
const defaultTimeout = 120
// timeout for long time progerss product, rds e.g.
const defaultLongTimeout = 800
const defaultLongTimeout = 1000
func getRegion(d *schema.ResourceData, meta interface{}) common.Region {
return meta.(*AliyunClient).Region
}
func notFoundError(err error) bool {
if e, ok := err.(*common.Error); ok && (e.StatusCode == 404 || e.ErrorResponse.Message == "Not found") {
if e, ok := err.(*common.Error); ok &&
(e.StatusCode == 404 || e.ErrorResponse.Message == "Not found" || e.Code == InstanceNotfound) {
return true
}
return false
}
// Protocal represents network protocal
type Protocal string
// Protocol represents network protocol
type Protocol string
// Constants of protocal definition
// Constants of protocol definition
const (
Http = Protocal("http")
Https = Protocal("https")
Tcp = Protocal("tcp")
Udp = Protocal("udp")
Http = Protocol("http")
Https = Protocol("https")
Tcp = Protocol("tcp")
Udp = Protocol("udp")
)
// ValidProtocals network protocal list
var ValidProtocals = []Protocal{Http, Https, Tcp, Udp}
// ValidProtocols network protocol list
var ValidProtocols = []Protocol{Http, Https, Tcp, Udp}
// simple array value check method, support string type only
func isProtocalValid(value string) bool {
func isProtocolValid(value string) bool {
res := false
for _, v := range ValidProtocals {
for _, v := range ValidProtocols {
if string(v) == value {
res = true
}
@ -77,4 +78,16 @@ const DB_DEFAULT_CONNECT_PORT = "3306"
const COMMA_SEPARATED = ","
const COLON_SEPARATED = ":"
const LOCAL_HOST_IP = "127.0.0.1"
// Takes the result of flatmap.Expand for an array of strings
// and returns a []string
func expandStringList(configured []interface{}) []string {
vs := make([]string, 0, len(configured))
for _, v := range configured {
vs = append(vs, v.(string))
}
return vs
}

View File

@ -5,6 +5,7 @@ import (
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
"github.com/denverdino/aliyungo/ess"
"github.com/denverdino/aliyungo/rds"
"github.com/denverdino/aliyungo/slb"
)
@ -20,6 +21,7 @@ type Config struct {
type AliyunClient struct {
Region common.Region
ecsconn *ecs.Client
essconn *ess.Client
rdsconn *rds.Client
// use new version
ecsNewconn *ecs.Client
@ -60,6 +62,11 @@ func (c *Config) Client() (*AliyunClient, error) {
return nil, err
}
essconn, err := c.essConn()
if err != nil {
return nil, err
}
return &AliyunClient{
Region: c.Region,
ecsconn: ecsconn,
@ -67,6 +74,7 @@ func (c *Config) Client() (*AliyunClient, error) {
vpcconn: vpcconn,
slbconn: slbconn,
rdsconn: rdsconn,
essconn: essconn,
}, nil
}
@ -123,3 +131,8 @@ func (c *Config) vpcConn() (*ecs.Client, error) {
return client, nil
}
func (c *Config) essConn() (*ess.Client, error) {
client := ess.NewESSClient(c.AccessKey, c.SecretKey, c.Region)
client.SetBusinessInfo(BusinessInfoKey)
return client, nil
}

View File

@ -1,5 +1,7 @@
package alicloud
import "github.com/denverdino/aliyungo/common"
const (
// common
Notfound = "Not found"
@ -25,7 +27,23 @@ const (
//Nat gateway
NatGatewayInvalidRegionId = "Invalid.RegionId"
DependencyViolationBandwidthPackages = "DependencyViolation.BandwidthPackages"
NotFindSnatEntryBySnatId = "NotFindSnatEntryBySnatId"
NotFindForwardEntryByForwardId = "NotFindForwardEntryByForwardId"
// vswitch
VswitcInvalidRegionId = "InvalidRegionId.NotFound"
// ess
InvalidScalingGroupIdNotFound = "InvalidScalingGroupId.NotFound"
IncorrectScalingConfigurationLifecycleState = "IncorrectScalingConfigurationLifecycleState"
)
func GetNotFoundErrorFromString(str string) error {
return &common.Error{
ErrorResponse: common.ErrorResponse{
Code: InstanceNotfound,
Message: str,
},
StatusCode: -1,
}
}

View File

@ -38,18 +38,24 @@ func Provider() terraform.ResourceProvider {
"alicloud_instance_types": dataSourceAlicloudInstanceTypes(),
},
ResourcesMap: map[string]*schema.Resource{
"alicloud_instance": resourceAliyunInstance(),
"alicloud_disk": resourceAliyunDisk(),
"alicloud_disk_attachment": resourceAliyunDiskAttachment(),
"alicloud_security_group": resourceAliyunSecurityGroup(),
"alicloud_security_group_rule": resourceAliyunSecurityGroupRule(),
"alicloud_db_instance": resourceAlicloudDBInstance(),
"alicloud_vpc": resourceAliyunVpc(),
"alicloud_nat_gateway": resourceAliyunNatGateway(),
"alicloud_instance": resourceAliyunInstance(),
"alicloud_disk": resourceAliyunDisk(),
"alicloud_disk_attachment": resourceAliyunDiskAttachment(),
"alicloud_security_group": resourceAliyunSecurityGroup(),
"alicloud_security_group_rule": resourceAliyunSecurityGroupRule(),
"alicloud_db_instance": resourceAlicloudDBInstance(),
"alicloud_ess_scaling_group": resourceAlicloudEssScalingGroup(),
"alicloud_ess_scaling_configuration": resourceAlicloudEssScalingConfiguration(),
"alicloud_ess_scaling_rule": resourceAlicloudEssScalingRule(),
"alicloud_ess_schedule": resourceAlicloudEssSchedule(),
"alicloud_vpc": resourceAliyunVpc(),
"alicloud_nat_gateway": resourceAliyunNatGateway(),
//both subnet and vswith exists,cause compatible old version, and compatible aws habit.
"alicloud_subnet": resourceAliyunSubnet(),
"alicloud_vswitch": resourceAliyunSubnet(),
"alicloud_route_entry": resourceAliyunRouteEntry(),
"alicloud_snat_entry": resourceAliyunSnatEntry(),
"alicloud_forward_entry": resourceAliyunForwardEntry(),
"alicloud_eip": resourceAliyunEip(),
"alicloud_eip_association": resourceAliyunEipAssociation(),
"alicloud_slb": resourceAliyunSlb(),

View File

@ -218,7 +218,7 @@ func resourceAlicloudDBInstanceCreate(d *schema.ResourceData, meta interface{})
// wait instance status change from Creating to running
if err := conn.WaitForInstance(d.Id(), rds.Running, defaultLongTimeout); err != nil {
log.Printf("[DEBUG] WaitForInstance %s got error: %#v", rds.Running, err)
return fmt.Errorf("WaitForInstance %s got error: %#v", rds.Running, err)
}
if err := modifySecurityIps(d.Id(), d.Get("security_ips"), meta); err != nil {
@ -386,6 +386,11 @@ func resourceAlicloudDBInstanceRead(d *schema.ResourceData, meta interface{}) er
if err != nil {
return err
}
if resp.Databases.Database == nil {
d.SetId("")
return nil
}
d.Set("db_mappings", flattenDatabaseMappings(resp.Databases.Database))
argn := rds.DescribeDBInstanceNetInfoArgs{

View File

@ -535,7 +535,7 @@ func testAccCheckDBInstanceDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_db_instance.foo" {
if rs.Type != "alicloud_db_instance" {
continue
}

View File

@ -78,7 +78,14 @@ func resourceAliyunEipRead(d *schema.ResourceData, meta interface{}) error {
d.SetId("")
return nil
}
return err
return fmt.Errorf("Error Describe Eip Attribute: %#v", err)
}
if eip.InstanceId != "" {
d.Set("instance", eip.InstanceId)
} else {
d.Set("instance", "")
return nil
}
bandwidth, _ := strconv.Atoi(eip.Bandwidth)
@ -87,12 +94,6 @@ func resourceAliyunEipRead(d *schema.ResourceData, meta interface{}) error {
d.Set("ip_address", eip.IpAddress)
d.Set("status", eip.Status)
if eip.InstanceId != "" {
d.Set("instance", eip.InstanceId)
} else {
d.Set("instance", "")
}
return nil
}

View File

@ -66,7 +66,7 @@ func resourceAliyunEipAssociationRead(d *schema.ResourceData, meta interface{})
d.SetId("")
return nil
}
return err
return fmt.Errorf("Error Describe Eip Attribute: %#v", err)
}
if eip.InstanceId != instanceId {

View File

@ -0,0 +1,320 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"strings"
"time"
)
func resourceAlicloudEssScalingConfiguration() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunEssScalingConfigurationCreate,
Read: resourceAliyunEssScalingConfigurationRead,
Update: resourceAliyunEssScalingConfigurationUpdate,
Delete: resourceAliyunEssScalingConfigurationDelete,
Schema: map[string]*schema.Schema{
"active": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"enable": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"scaling_group_id": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"image_id": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"instance_type": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"io_optimized": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateIoOptimized,
},
"security_group_id": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Required: true,
},
"scaling_configuration_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"internet_charge_type": &schema.Schema{
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Computed: true,
ValidateFunc: validateInternetChargeType,
},
"internet_max_bandwidth_in": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Computed: true,
},
"internet_max_bandwidth_out": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
ValidateFunc: validateInternetMaxBandWidthOut,
},
"system_disk_category": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: validateAllowedStringValue([]string{
string(ecs.DiskCategoryCloud),
string(ecs.DiskCategoryCloudSSD),
string(ecs.DiskCategoryCloudEfficiency),
string(ecs.DiskCategoryEphemeralSSD),
}),
},
"data_disk": &schema.Schema{
Optional: true,
ForceNew: true,
Type: schema.TypeList,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"size": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},
"category": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"snapshot_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"device": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
},
},
"instance_ids": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
MaxItems: 20,
},
},
}
}
func resourceAliyunEssScalingConfigurationCreate(d *schema.ResourceData, meta interface{}) error {
args, err := buildAlicloudEssScalingConfigurationArgs(d, meta)
if err != nil {
return err
}
essconn := meta.(*AliyunClient).essconn
scaling, err := essconn.CreateScalingConfiguration(args)
if err != nil {
return err
}
d.SetId(d.Get("scaling_group_id").(string) + COLON_SEPARATED + scaling.ScalingConfigurationId)
return resourceAliyunEssScalingConfigurationUpdate(d, meta)
}
func resourceAliyunEssScalingConfigurationUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
if d.HasChange("active") {
active := d.Get("active").(bool)
if !active {
return fmt.Errorf("Please active the scaling configuration directly.")
}
ids := strings.Split(d.Id(), COLON_SEPARATED)
err := client.ActiveScalingConfigurationById(ids[0], ids[1])
if err != nil {
return fmt.Errorf("Active scaling configuration %s err: %#v", ids[1], err)
}
}
if err := enableEssScalingConfiguration(d, meta); err != nil {
return err
}
return resourceAliyunEssScalingConfigurationRead(d, meta)
}
func enableEssScalingConfiguration(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ids := strings.Split(d.Id(), COLON_SEPARATED)
if d.HasChange("enable") {
d.SetPartial("enable")
enable := d.Get("enable").(bool)
if !enable {
err := client.DisableScalingConfigurationById(ids[0])
if err != nil {
return fmt.Errorf("Disable scaling group %s err: %#v", ids[0], err)
}
}
instance_ids := []string{}
if d.HasChange("instance_ids") {
d.SetPartial("instance_ids")
instances := d.Get("instance_ids").([]interface{})
instance_ids = expandStringList(instances)
}
err := client.EnableScalingConfigurationById(ids[0], ids[1], instance_ids)
if err != nil {
return fmt.Errorf("Enable scaling configuration %s err: %#v", ids[1], err)
}
}
return nil
}
func resourceAliyunEssScalingConfigurationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ids := strings.Split(d.Id(), COLON_SEPARATED)
c, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
if err != nil {
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
d.SetId("")
return nil
}
return fmt.Errorf("Error Describe ESS scaling configuration Attribute: %#v", err)
}
d.Set("scaling_group_id", c.ScalingGroupId)
d.Set("active", c.LifecycleState == ess.Active)
d.Set("image_id", c.ImageId)
d.Set("instance_type", c.InstanceType)
d.Set("io_optimized", c.IoOptimized)
d.Set("security_group_id", c.SecurityGroupId)
d.Set("scaling_configuration_name", c.ScalingConfigurationName)
d.Set("internet_charge_type", c.InternetChargeType)
d.Set("internet_max_bandwidth_in", c.InternetMaxBandwidthIn)
d.Set("internet_max_bandwidth_out", c.InternetMaxBandwidthOut)
d.Set("system_disk_category", c.SystemDiskCategory)
d.Set("data_disk", flattenDataDiskMappings(c.DataDisks.DataDisk))
return nil
}
func resourceAliyunEssScalingConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
return resource.Retry(5*time.Minute, func() *resource.RetryError {
ids := strings.Split(d.Id(), COLON_SEPARATED)
err := client.DeleteScalingConfigurationById(ids[0], ids[1])
if err != nil {
e, _ := err.(*common.Error)
if e.ErrorResponse.Code == IncorrectScalingConfigurationLifecycleState {
return resource.NonRetryableError(
fmt.Errorf("Scaling configuration is active - please active another one and trying again."))
}
if e.ErrorResponse.Code != InvalidScalingGroupIdNotFound {
return resource.RetryableError(
fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
}
}
_, err = client.DescribeScalingConfigurationById(ids[0], ids[1])
if err != nil {
if notFoundError(err) {
return nil
}
return resource.NonRetryableError(err)
}
return resource.RetryableError(
fmt.Errorf("Scaling configuration in use - trying again while it is deleted."))
})
}
func buildAlicloudEssScalingConfigurationArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingConfigurationArgs, error) {
args := &ess.CreateScalingConfigurationArgs{
ScalingGroupId: d.Get("scaling_group_id").(string),
ImageId: d.Get("image_id").(string),
InstanceType: d.Get("instance_type").(string),
IoOptimized: ecs.IoOptimized(d.Get("io_optimized").(string)),
SecurityGroupId: d.Get("security_group_id").(string),
}
if v := d.Get("scaling_configuration_name").(string); v != "" {
args.ScalingConfigurationName = v
}
if v := d.Get("internet_charge_type").(string); v != "" {
args.InternetChargeType = common.InternetChargeType(v)
}
if v := d.Get("internet_max_bandwidth_in").(int); v != 0 {
args.InternetMaxBandwidthIn = v
}
if v := d.Get("internet_max_bandwidth_out").(int); v != 0 {
args.InternetMaxBandwidthOut = v
}
if v := d.Get("system_disk_category").(string); v != "" {
args.SystemDisk_Category = common.UnderlineString(v)
}
dds, ok := d.GetOk("data_disk")
if ok {
disks := dds.([]interface{})
diskTypes := []ess.DataDiskType{}
for _, e := range disks {
pack := e.(map[string]interface{})
disk := ess.DataDiskType{
Size: pack["size"].(int),
Category: pack["category"].(string),
SnapshotId: pack["snapshot_id"].(string),
Device: pack["device"].(string),
}
if v := pack["size"].(int); v != 0 {
disk.Size = v
}
if v := pack["category"].(string); v != "" {
disk.Category = v
}
if v := pack["snapshot_id"].(string); v != "" {
disk.SnapshotId = v
}
if v := pack["device"].(string); v != "" {
disk.Device = v
}
diskTypes = append(diskTypes, disk)
}
args.DataDisk = diskTypes
}
return args, nil
}

View File

@ -0,0 +1,495 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"log"
"regexp"
"strings"
"testing"
)
func TestAccAlicloudEssScalingConfiguration_basic(t *testing.T) {
var sc ess.ScalingConfigurationItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_configuration.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingConfigurationConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingConfigurationExists(
"alicloud_ess_scaling_configuration.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"instance_type",
"ecs.s2.large"),
resource.TestMatchResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"image_id",
regexp.MustCompile("^centos_6")),
),
},
},
})
}
func TestAccAlicloudEssScalingConfiguration_multiConfig(t *testing.T) {
var sc ess.ScalingConfigurationItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_configuration.bar",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingConfiguration_multiConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingConfigurationExists(
"alicloud_ess_scaling_configuration.bar", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"active",
"false"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"instance_type",
"ecs.s2.large"),
resource.TestMatchResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"image_id",
regexp.MustCompile("^centos_6")),
),
},
},
})
}
func SkipTestAccAlicloudEssScalingConfiguration_active(t *testing.T) {
var sc ess.ScalingConfigurationItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_configuration.bar",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingConfiguration_active,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingConfigurationExists(
"alicloud_ess_scaling_configuration.bar", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"active",
"true"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"instance_type",
"ecs.s2.large"),
resource.TestMatchResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"image_id",
regexp.MustCompile("^centos_6")),
),
},
resource.TestStep{
Config: testAccEssScalingConfiguration_inActive,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingConfigurationExists(
"alicloud_ess_scaling_configuration.bar", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"active",
"false"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"instance_type",
"ecs.s2.large"),
resource.TestMatchResourceAttr(
"alicloud_ess_scaling_configuration.bar",
"image_id",
regexp.MustCompile("^centos_6")),
),
},
},
})
}
func SkipTestAccAlicloudEssScalingConfiguration_enable(t *testing.T) {
var sc ess.ScalingConfigurationItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_configuration.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingConfigurationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingConfiguration_enable,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingConfigurationExists(
"alicloud_ess_scaling_configuration.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"enable",
"true"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"instance_type",
"ecs.s2.large"),
resource.TestMatchResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"image_id",
regexp.MustCompile("^centos_6")),
),
},
resource.TestStep{
Config: testAccEssScalingConfiguration_disable,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingConfigurationExists(
"alicloud_ess_scaling_configuration.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"enable",
"false"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"instance_type",
"ecs.s2.large"),
resource.TestMatchResourceAttr(
"alicloud_ess_scaling_configuration.foo",
"image_id",
regexp.MustCompile("^centos_6")),
),
},
},
})
}
func testAccCheckEssScalingConfigurationExists(n string, d *ess.ScalingConfigurationItemType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ESS Scaling Configuration ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
attr, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
log.Printf("[DEBUG] check scaling configuration %s attribute %#v", rs.Primary.ID, attr)
if err != nil {
return err
}
if attr == nil {
return fmt.Errorf("Scaling Configuration not found")
}
*d = *attr
return nil
}
}
func testAccCheckEssScalingConfigurationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_ess_scaling_configuration" {
continue
}
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
ins, err := client.DescribeScalingConfigurationById(ids[0], ids[1])
if ins != nil {
return fmt.Errorf("Error ESS scaling configuration still exist")
}
// Verify the error is what we want
if err != nil {
// Verify the error is what we want
e, _ := err.(*common.Error)
if e.ErrorResponse.Code == InstanceNotfound {
continue
}
return err
}
}
return nil
}
const testAccEssScalingConfigurationConfig = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`
const testAccEssScalingConfiguration_multiConfig = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
resource "alicloud_ess_scaling_configuration" "bar" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`
const testAccEssScalingConfiguration_active = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
active = true
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`
const testAccEssScalingConfiguration_inActive = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
active = false
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`
const testAccEssScalingConfiguration_enable = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
enable = true
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`
const testAccEssScalingConfiguration_disable = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
enable = false
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`

View File

@ -0,0 +1,209 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"strings"
"time"
)
func resourceAlicloudEssScalingGroup() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunEssScalingGroupCreate,
Read: resourceAliyunEssScalingGroupRead,
Update: resourceAliyunEssScalingGroupUpdate,
Delete: resourceAliyunEssScalingGroupDelete,
Schema: map[string]*schema.Schema{
"min_size": &schema.Schema{
Type: schema.TypeInt,
Required: true,
ValidateFunc: validateIntegerInRange(0, 100),
},
"max_size": &schema.Schema{
Type: schema.TypeInt,
Required: true,
ValidateFunc: validateIntegerInRange(0, 100),
},
"scaling_group_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"default_cooldown": &schema.Schema{
Type: schema.TypeInt,
Default: 300,
Optional: true,
ValidateFunc: validateIntegerInRange(0, 86400),
},
"vswitch_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"removal_policies": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
MaxItems: 2,
},
"db_instance_ids": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
MaxItems: 3,
},
"loadbalancer_ids": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
},
}
}
func resourceAliyunEssScalingGroupCreate(d *schema.ResourceData, meta interface{}) error {
args, err := buildAlicloudEssScalingGroupArgs(d, meta)
if err != nil {
return err
}
essconn := meta.(*AliyunClient).essconn
scaling, err := essconn.CreateScalingGroup(args)
if err != nil {
return err
}
d.SetId(scaling.ScalingGroupId)
return resourceAliyunEssScalingGroupUpdate(d, meta)
}
func resourceAliyunEssScalingGroupRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
scaling, err := client.DescribeScalingGroupById(d.Id())
if err != nil {
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
d.SetId("")
return nil
}
return fmt.Errorf("Error Describe ESS scaling group Attribute: %#v", err)
}
d.Set("min_size", scaling.MinSize)
d.Set("max_size", scaling.MaxSize)
d.Set("scaling_group_name", scaling.ScalingGroupName)
d.Set("default_cooldown", scaling.DefaultCooldown)
d.Set("removal_policies", scaling.RemovalPolicies)
d.Set("db_instance_ids", scaling.DBInstanceIds)
d.Set("loadbalancer_ids", scaling.LoadBalancerId)
return nil
}
func resourceAliyunEssScalingGroupUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AliyunClient).essconn
args := &ess.ModifyScalingGroupArgs{
ScalingGroupId: d.Id(),
}
if d.HasChange("scaling_group_name") {
args.ScalingGroupName = d.Get("scaling_group_name").(string)
}
if d.HasChange("min_size") {
args.MinSize = d.Get("min_size").(int)
}
if d.HasChange("max_size") {
args.MaxSize = d.Get("max_size").(int)
}
if d.HasChange("default_cooldown") {
args.DefaultCooldown = d.Get("default_cooldown").(int)
}
if d.HasChange("removal_policies") {
policyStrings := d.Get("removal_policies").([]interface{})
args.RemovalPolicy = expandStringList(policyStrings)
}
if _, err := conn.ModifyScalingGroup(args); err != nil {
return err
}
return resourceAliyunEssScalingGroupRead(d, meta)
}
func resourceAliyunEssScalingGroupDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
return resource.Retry(2*time.Minute, func() *resource.RetryError {
err := client.DeleteScalingGroupById(d.Id())
if err != nil {
e, _ := err.(*common.Error)
if e.ErrorResponse.Code != InvalidScalingGroupIdNotFound {
return resource.RetryableError(fmt.Errorf("Scaling group in use - trying again while it is deleted."))
}
}
_, err = client.DescribeScalingGroupById(d.Id())
if err != nil {
if notFoundError(err) {
return nil
}
return resource.NonRetryableError(err)
}
return resource.RetryableError(fmt.Errorf("Scaling group in use - trying again while it is deleted."))
})
}
func buildAlicloudEssScalingGroupArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingGroupArgs, error) {
client := meta.(*AliyunClient)
args := &ess.CreateScalingGroupArgs{
RegionId: getRegion(d, meta),
MinSize: d.Get("min_size").(int),
MaxSize: d.Get("max_size").(int),
DefaultCooldown: d.Get("default_cooldown").(int),
}
if v := d.Get("scaling_group_name").(string); v != "" {
args.ScalingGroupName = v
}
if v := d.Get("vswitch_id").(string); v != "" {
args.VSwitchId = v
// get vpcId
vpcId, err := client.GetVpcIdByVSwitchId(v)
if err != nil {
return nil, fmt.Errorf("VswitchId %s is not valid of current region", v)
}
// fill vpcId by vswitchId
args.VpcId = vpcId
}
dbs, ok := d.GetOk("db_instance_ids")
if ok {
dbsStrings := dbs.([]interface{})
args.DBInstanceId = expandStringList(dbsStrings)
}
lbs, ok := d.GetOk("loadbalancer_ids")
if ok {
lbsStrings := lbs.([]interface{})
args.LoadBalancerId = strings.Join(expandStringList(lbsStrings), COMMA_SEPARATED)
}
return args, nil
}

View File

@ -0,0 +1,297 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"log"
"testing"
)
func TestAccAlicloudEssScalingGroup_basic(t *testing.T) {
var sg ess.ScalingGroupItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_group.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingGroupDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingGroupConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingGroupExists(
"alicloud_ess_scaling_group.foo", &sg),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"min_size",
"1"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"max_size",
"1"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"scaling_group_name",
"foo"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"removal_policies.#",
"2",
),
),
},
},
})
}
func TestAccAlicloudEssScalingGroup_update(t *testing.T) {
var sg ess.ScalingGroupItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_group.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingGroupDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingGroup,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingGroupExists(
"alicloud_ess_scaling_group.foo", &sg),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"min_size",
"1"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"max_size",
"1"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"scaling_group_name",
"foo"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"removal_policies.#",
"2",
),
),
},
resource.TestStep{
Config: testAccEssScalingGroup_update,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingGroupExists(
"alicloud_ess_scaling_group.foo", &sg),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"min_size",
"2"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"max_size",
"2"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"scaling_group_name",
"update"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"removal_policies.#",
"1",
),
),
},
},
})
}
func SkipTestAccAlicloudEssScalingGroup_vpc(t *testing.T) {
var sg ess.ScalingGroupItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_group.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingGroupDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingGroup_vpc,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingGroupExists(
"alicloud_ess_scaling_group.foo", &sg),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"min_size",
"1"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"max_size",
"1"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"scaling_group_name",
"foo"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_group.foo",
"removal_policies.#",
"2",
),
),
},
},
})
}
func testAccCheckEssScalingGroupExists(n string, d *ess.ScalingGroupItemType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ESS Scaling Group ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
attr, err := client.DescribeScalingGroupById(rs.Primary.ID)
log.Printf("[DEBUG] check scaling group %s attribute %#v", rs.Primary.ID, attr)
if err != nil {
return err
}
if attr == nil {
return fmt.Errorf("Scaling Group not found")
}
*d = *attr
return nil
}
}
func testAccCheckEssScalingGroupDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_ess_scaling_group" {
continue
}
ins, err := client.DescribeScalingGroupById(rs.Primary.ID)
if ins != nil {
return fmt.Errorf("Error ESS scaling group still exist")
}
// Verify the error is what we want
if err != nil {
// Verify the error is what we want
e, _ := err.(*common.Error)
if e.ErrorResponse.Code == InstanceNotfound {
continue
}
return err
}
}
return nil
}
const testAccEssScalingGroupConfig = `
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
`
const testAccEssScalingGroup = `
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
removal_policies = ["OldestInstance", "NewestInstance"]
}
`
const testAccEssScalingGroup_update = `
resource "alicloud_ess_scaling_group" "foo" {
min_size = 2
max_size = 2
scaling_group_name = "update"
removal_policies = ["OldestInstance"]
}
`
const testAccEssScalingGroup_vpc = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
data "alicloud_zones" "default" {
"available_disk_category"= "cloud_efficiency"
"available_resource_creation"= "VSwitch"
}
resource "alicloud_vpc" "foo" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
vpc_id = "${alicloud_vpc.foo.id}"
}
resource "alicloud_ess_scaling_group" "foo" {
min_size = 1
max_size = 1
scaling_group_name = "foo"
default_cooldown = 20
vswitch_id = "${alicloud_vswitch.foo.id}"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.foo.id}"
enable = true
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.n1.medium"
io_optimized = "optimized"
system_disk_category = "cloud_efficiency"
internet_charge_type = "PayByTraffic"
internet_max_bandwidth_out = 10
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
`

View File

@ -0,0 +1,168 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"strings"
"time"
)
func resourceAlicloudEssScalingRule() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunEssScalingRuleCreate,
Read: resourceAliyunEssScalingRuleRead,
Update: resourceAliyunEssScalingRuleUpdate,
Delete: resourceAliyunEssScalingRuleDelete,
Schema: map[string]*schema.Schema{
"scaling_group_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"adjustment_type": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAllowedStringValue([]string{string(ess.QuantityChangeInCapacity),
string(ess.PercentChangeInCapacity), string(ess.TotalCapacity)}),
},
"adjustment_value": &schema.Schema{
Type: schema.TypeInt,
Required: true,
},
"scaling_rule_name": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"ari": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"cooldown": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validateIntegerInRange(0, 86400),
},
},
}
}
func resourceAliyunEssScalingRuleCreate(d *schema.ResourceData, meta interface{}) error {
args, err := buildAlicloudEssScalingRuleArgs(d, meta)
if err != nil {
return err
}
essconn := meta.(*AliyunClient).essconn
rule, err := essconn.CreateScalingRule(args)
if err != nil {
return err
}
d.SetId(d.Get("scaling_group_id").(string) + COLON_SEPARATED + rule.ScalingRuleId)
return resourceAliyunEssScalingRuleUpdate(d, meta)
}
func resourceAliyunEssScalingRuleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ids := strings.Split(d.Id(), COLON_SEPARATED)
rule, err := client.DescribeScalingRuleById(ids[0], ids[1])
if err != nil {
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
d.SetId("")
return nil
}
return fmt.Errorf("Error Describe ESS scaling rule Attribute: %#v", err)
}
d.Set("scaling_group_id", rule.ScalingGroupId)
d.Set("ari", rule.ScalingRuleAri)
d.Set("adjustment_type", rule.AdjustmentType)
d.Set("adjustment_value", rule.AdjustmentValue)
d.Set("scaling_rule_name", rule.ScalingRuleName)
d.Set("cooldown", rule.Cooldown)
return nil
}
func resourceAliyunEssScalingRuleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ids := strings.Split(d.Id(), COLON_SEPARATED)
return resource.Retry(2*time.Minute, func() *resource.RetryError {
err := client.DeleteScalingRuleById(ids[1])
if err != nil {
return resource.RetryableError(fmt.Errorf("Scaling rule in use - trying again while it is deleted."))
}
_, err = client.DescribeScalingRuleById(ids[0], ids[1])
if err != nil {
if notFoundError(err) {
return nil
}
return resource.NonRetryableError(err)
}
return resource.RetryableError(fmt.Errorf("Scaling rule in use - trying again while it is deleted."))
})
}
func resourceAliyunEssScalingRuleUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AliyunClient).essconn
ids := strings.Split(d.Id(), COLON_SEPARATED)
args := &ess.ModifyScalingRuleArgs{
ScalingRuleId: ids[1],
}
if d.HasChange("adjustment_type") {
args.AdjustmentType = ess.AdjustmentType(d.Get("adjustment_type").(string))
}
if d.HasChange("adjustment_value") {
args.AdjustmentValue = d.Get("adjustment_value").(int)
}
if d.HasChange("scaling_rule_name") {
args.ScalingRuleName = d.Get("scaling_rule_name").(string)
}
if d.HasChange("cooldown") {
args.Cooldown = d.Get("cooldown").(int)
}
if _, err := conn.ModifyScalingRule(args); err != nil {
return err
}
return resourceAliyunEssScalingRuleRead(d, meta)
}
func buildAlicloudEssScalingRuleArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScalingRuleArgs, error) {
args := &ess.CreateScalingRuleArgs{
RegionId: getRegion(d, meta),
ScalingGroupId: d.Get("scaling_group_id").(string),
AdjustmentType: ess.AdjustmentType(d.Get("adjustment_type").(string)),
AdjustmentValue: d.Get("adjustment_value").(int),
}
if v := d.Get("scaling_rule_name").(string); v != "" {
args.ScalingRuleName = v
}
if v := d.Get("cooldown").(int); v != 0 {
args.Cooldown = v
}
return args, nil
}

View File

@ -0,0 +1,290 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"log"
"strings"
"testing"
)
func TestAccAlicloudEssScalingRule_basic(t *testing.T) {
var sc ess.ScalingRuleItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_rule.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingRuleConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingRuleExists(
"alicloud_ess_scaling_rule.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_rule.foo",
"adjustment_type",
"TotalCapacity"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_rule.foo",
"adjustment_value",
"1"),
),
},
},
})
}
func TestAccAlicloudEssScalingRule_update(t *testing.T) {
var sc ess.ScalingRuleItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_scaling_rule.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScalingRuleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScalingRule,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingRuleExists(
"alicloud_ess_scaling_rule.foo", &sc),
testAccCheckEssScalingRuleExists(
"alicloud_ess_scaling_rule.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_rule.foo",
"adjustment_type",
"TotalCapacity"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_rule.foo",
"adjustment_value",
"1"),
),
},
resource.TestStep{
Config: testAccEssScalingRule_update,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScalingRuleExists(
"alicloud_ess_scaling_rule.foo", &sc),
testAccCheckEssScalingRuleExists(
"alicloud_ess_scaling_rule.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_rule.foo",
"adjustment_type",
"TotalCapacity"),
resource.TestCheckResourceAttr(
"alicloud_ess_scaling_rule.foo",
"adjustment_value",
"2"),
),
},
},
})
}
func testAccCheckEssScalingRuleExists(n string, d *ess.ScalingRuleItemType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ESS Scaling Rule ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
attr, err := client.DescribeScalingRuleById(ids[0], ids[1])
log.Printf("[DEBUG] check scaling rule %s attribute %#v", rs.Primary.ID, attr)
if err != nil {
return err
}
if attr == nil {
return fmt.Errorf("Scaling rule not found")
}
*d = *attr
return nil
}
}
func testAccCheckEssScalingRuleDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_ess_scaling_rule" {
continue
}
ids := strings.Split(rs.Primary.ID, COLON_SEPARATED)
ins, err := client.DescribeScalingRuleById(ids[0], ids[1])
if ins != nil {
return fmt.Errorf("Error ESS scaling rule still exist")
}
// Verify the error is what we want
if err != nil {
// Verify the error is what we want
e, _ := err.(*common.Error)
if e.ErrorResponse.Code == InstanceNotfound {
continue
}
return err
}
}
return nil
}
const testAccEssScalingRuleConfig = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "bar" {
min_size = 1
max_size = 1
scaling_group_name = "bar"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
resource "alicloud_ess_scaling_rule" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
adjustment_type = "TotalCapacity"
adjustment_value = 1
cooldown = 120
}
`
const testAccEssScalingRule = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "bar" {
min_size = 1
max_size = 1
scaling_group_name = "bar"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
resource "alicloud_ess_scaling_rule" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
adjustment_type = "TotalCapacity"
adjustment_value = 1
cooldown = 120
}
`
const testAccEssScalingRule_update = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "bar" {
min_size = 1
max_size = 1
scaling_group_name = "bar"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
resource "alicloud_ess_scaling_rule" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
adjustment_type = "TotalCapacity"
adjustment_value = 2
cooldown = 60
}
`

View File

@ -0,0 +1,220 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"time"
)
func resourceAlicloudEssSchedule() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunEssScheduleCreate,
Read: resourceAliyunEssScheduleRead,
Update: resourceAliyunEssScheduleUpdate,
Delete: resourceAliyunEssScheduleDelete,
Schema: map[string]*schema.Schema{
"scheduled_action": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"launch_time": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"scheduled_task_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"description": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"launch_expiration_time": &schema.Schema{
Type: schema.TypeInt,
Default: 600,
Optional: true,
ValidateFunc: validateIntegerInRange(0, 21600),
},
"recurrence_type": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
ValidateFunc: validateAllowedStringValue([]string{string(ess.Daily),
string(ess.Weekly), string(ess.Monthly)}),
},
"recurrence_value": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"recurrence_end_time": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
},
"task_enabled": &schema.Schema{
Type: schema.TypeBool,
Default: true,
Optional: true,
},
},
}
}
func resourceAliyunEssScheduleCreate(d *schema.ResourceData, meta interface{}) error {
args, err := buildAlicloudEssScheduleArgs(d, meta)
if err != nil {
return err
}
essconn := meta.(*AliyunClient).essconn
rule, err := essconn.CreateScheduledTask(args)
if err != nil {
return err
}
d.SetId(rule.ScheduledTaskId)
return resourceAliyunEssScheduleUpdate(d, meta)
}
func resourceAliyunEssScheduleRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
rule, err := client.DescribeScheduleById(d.Id())
if err != nil {
if e, ok := err.(*common.Error); ok && e.Code == InstanceNotfound {
d.SetId("")
return nil
}
return fmt.Errorf("Error Describe ESS schedule Attribute: %#v", err)
}
d.Set("scheduled_action", rule.ScheduledAction)
d.Set("launch_time", rule.LaunchTime)
d.Set("scheduled_task_name", rule.ScheduledTaskName)
d.Set("description", rule.Description)
d.Set("launch_expiration_time", rule.LaunchExpirationTime)
d.Set("recurrence_type", rule.RecurrenceType)
d.Set("recurrence_value", rule.RecurrenceValue)
d.Set("recurrence_end_time", rule.RecurrenceEndTime)
d.Set("task_enabled", rule.TaskEnabled)
return nil
}
func resourceAliyunEssScheduleUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AliyunClient).essconn
args := &ess.ModifyScheduledTaskArgs{
ScheduledTaskId: d.Id(),
}
if d.HasChange("scheduled_task_name") {
args.ScheduledTaskName = d.Get("scheduled_task_name").(string)
}
if d.HasChange("description") {
args.Description = d.Get("description").(string)
}
if d.HasChange("scheduled_action") {
args.ScheduledAction = d.Get("scheduled_action").(string)
}
if d.HasChange("launch_time") {
args.LaunchTime = d.Get("launch_time").(string)
}
if d.HasChange("launch_expiration_time") {
args.LaunchExpirationTime = d.Get("launch_expiration_time").(int)
}
if d.HasChange("recurrence_type") {
args.RecurrenceType = ess.RecurrenceType(d.Get("recurrence_type").(string))
}
if d.HasChange("recurrence_value") {
args.RecurrenceValue = d.Get("recurrence_value").(string)
}
if d.HasChange("recurrence_end_time") {
args.RecurrenceEndTime = d.Get("recurrence_end_time").(string)
}
if d.HasChange("task_enabled") {
args.TaskEnabled = d.Get("task_enabled").(bool)
}
if _, err := conn.ModifyScheduledTask(args); err != nil {
return err
}
return resourceAliyunEssScheduleRead(d, meta)
}
func resourceAliyunEssScheduleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
return resource.Retry(2*time.Minute, func() *resource.RetryError {
err := client.DeleteScheduleById(d.Id())
if err != nil {
return resource.RetryableError(fmt.Errorf("Scaling schedule in use - trying again while it is deleted."))
}
_, err = client.DescribeScheduleById(d.Id())
if err != nil {
if notFoundError(err) {
return nil
}
return resource.NonRetryableError(err)
}
return resource.RetryableError(fmt.Errorf("Scaling schedule in use - trying again while it is deleted."))
})
}
func buildAlicloudEssScheduleArgs(d *schema.ResourceData, meta interface{}) (*ess.CreateScheduledTaskArgs, error) {
args := &ess.CreateScheduledTaskArgs{
RegionId: getRegion(d, meta),
ScheduledAction: d.Get("scheduled_action").(string),
LaunchTime: d.Get("launch_time").(string),
TaskEnabled: d.Get("task_enabled").(bool),
}
if v := d.Get("scheduled_task_name").(string); v != "" {
args.ScheduledTaskName = v
}
if v := d.Get("description").(string); v != "" {
args.Description = v
}
if v := d.Get("recurrence_type").(string); v != "" {
args.RecurrenceType = ess.RecurrenceType(v)
}
if v := d.Get("recurrence_value").(string); v != "" {
args.RecurrenceValue = v
}
if v := d.Get("recurrence_end_time").(string); v != "" {
args.RecurrenceEndTime = v
}
if v := d.Get("launch_expiration_time").(int); v != 0 {
args.LaunchExpirationTime = v
}
return args, nil
}

View File

@ -0,0 +1,151 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ess"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"log"
"testing"
)
func TestAccAlicloudEssSchedule_basic(t *testing.T) {
var sc ess.ScheduledTaskItemType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_ess_schedule.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckEssScheduleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccEssScheduleConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckEssScheduleExists(
"alicloud_ess_schedule.foo", &sc),
resource.TestCheckResourceAttr(
"alicloud_ess_schedule.foo",
"launch_time",
"2017-04-29T07:30Z"),
resource.TestCheckResourceAttr(
"alicloud_ess_schedule.foo",
"task_enabled",
"true"),
),
},
},
})
}
func testAccCheckEssScheduleExists(n string, d *ess.ScheduledTaskItemType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ESS Schedule ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
attr, err := client.DescribeScheduleById(rs.Primary.ID)
log.Printf("[DEBUG] check schedule %s attribute %#v", rs.Primary.ID, attr)
if err != nil {
return err
}
if attr == nil {
return fmt.Errorf("Ess schedule not found")
}
*d = *attr
return nil
}
}
func testAccCheckEssScheduleDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_ess_schedule" {
continue
}
ins, err := client.DescribeScheduleById(rs.Primary.ID)
if ins != nil {
return fmt.Errorf("Error ESS schedule still exist")
}
// Verify the error is what we want
if err != nil {
// Verify the error is what we want
e, _ := err.(*common.Error)
if e.ErrorResponse.Code == InstanceNotfound {
continue
}
return err
}
}
return nil
}
const testAccEssScheduleConfig = `
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "tf_test_foo" {
name = "tf_test_foo"
description = "foo"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "bar" {
min_size = 1
max_size = 1
scaling_group_name = "bar"
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "ecs.s2.large"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.tf_test_foo.id}"
}
resource "alicloud_ess_scaling_rule" "foo" {
scaling_group_id = "${alicloud_ess_scaling_group.bar.id}"
adjustment_type = "TotalCapacity"
adjustment_value = 2
cooldown = 60
}
resource "alicloud_ess_schedule" "foo" {
scheduled_action = "${alicloud_ess_scaling_rule.foo.ari}"
launch_time = "2017-04-29T07:30Z"
scheduled_task_name = "tf-foo"
}
`

View File

@ -0,0 +1,165 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceAliyunForwardEntry() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunForwardEntryCreate,
Read: resourceAliyunForwardEntryRead,
Update: resourceAliyunForwardEntryUpdate,
Delete: resourceAliyunForwardEntryDelete,
Schema: map[string]*schema.Schema{
"forward_table_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"external_ip": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"external_port": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateForwardPort,
},
"ip_protocol": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateAllowedStringValue([]string{"tcp", "udp", "any"}),
},
"internal_ip": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"internal_port": &schema.Schema{
Type: schema.TypeString,
Required: true,
ValidateFunc: validateForwardPort,
},
},
}
}
func resourceAliyunForwardEntryCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AliyunClient).vpcconn
args := &ecs.CreateForwardEntryArgs{
RegionId: getRegion(d, meta),
ForwardTableId: d.Get("forward_table_id").(string),
ExternalIp: d.Get("external_ip").(string),
ExternalPort: d.Get("external_port").(string),
IpProtocol: d.Get("ip_protocol").(string),
InternalIp: d.Get("internal_ip").(string),
InternalPort: d.Get("internal_port").(string),
}
resp, err := conn.CreateForwardEntry(args)
if err != nil {
return fmt.Errorf("CreateForwardEntry got error: %#v", err)
}
d.SetId(resp.ForwardEntryId)
d.Set("forward_table_id", d.Get("forward_table_id").(string))
return resourceAliyunForwardEntryRead(d, meta)
}
func resourceAliyunForwardEntryRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
forwardEntry, err := client.DescribeForwardEntry(d.Get("forward_table_id").(string), d.Id())
if err != nil {
if notFoundError(err) {
return nil
}
return err
}
d.Set("forward_table_id", forwardEntry.ForwardTableId)
d.Set("external_ip", forwardEntry.ExternalIp)
d.Set("external_port", forwardEntry.ExternalPort)
d.Set("ip_protocol", forwardEntry.IpProtocol)
d.Set("internal_ip", forwardEntry.InternalIp)
d.Set("internal_port", forwardEntry.InternalPort)
return nil
}
func resourceAliyunForwardEntryUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
conn := client.vpcconn
forwardEntry, err := client.DescribeForwardEntry(d.Get("forward_table_id").(string), d.Id())
if err != nil {
return err
}
d.Partial(true)
attributeUpdate := false
args := &ecs.ModifyForwardEntryArgs{
RegionId: getRegion(d, meta),
ForwardTableId: forwardEntry.ForwardTableId,
ForwardEntryId: forwardEntry.ForwardEntryId,
ExternalIp: forwardEntry.ExternalIp,
IpProtocol: forwardEntry.IpProtocol,
ExternalPort: forwardEntry.ExternalPort,
InternalIp: forwardEntry.InternalIp,
InternalPort: forwardEntry.InternalPort,
}
if d.HasChange("external_port") {
d.SetPartial("external_port")
args.ExternalPort = d.Get("external_port").(string)
attributeUpdate = true
}
if d.HasChange("ip_protocol") {
d.SetPartial("ip_protocol")
args.IpProtocol = d.Get("ip_protocol").(string)
attributeUpdate = true
}
if d.HasChange("internal_port") {
d.SetPartial("internal_port")
args.InternalPort = d.Get("internal_port").(string)
attributeUpdate = true
}
if attributeUpdate {
if err := conn.ModifyForwardEntry(args); err != nil {
return err
}
}
d.Partial(false)
return resourceAliyunForwardEntryRead(d, meta)
}
func resourceAliyunForwardEntryDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
conn := client.vpcconn
forwardEntryId := d.Id()
forwardTableId := d.Get("forward_table_id").(string)
args := &ecs.DeleteForwardEntryArgs{
RegionId: getRegion(d, meta),
ForwardTableId: forwardTableId,
ForwardEntryId: forwardEntryId,
}
if err := conn.DeleteForwardEntry(args); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,216 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"testing"
)
func TestAccAlicloudForward_basic(t *testing.T) {
var forward ecs.ForwardTableEntrySetType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_forward_entry.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckForwardEntryDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccForwardEntryConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckForwardEntryExists(
"alicloud_forward_entry.foo", &forward),
),
},
resource.TestStep{
Config: testAccForwardEntryUpdate,
Check: resource.ComposeTestCheckFunc(
testAccCheckForwardEntryExists(
"alicloud_forward_entry.foo", &forward),
),
},
},
})
}
func testAccCheckForwardEntryDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_snat_entry" {
continue
}
// Try to find the Snat entry
instance, err := client.DescribeForwardEntry(rs.Primary.Attributes["forward_table_id"], rs.Primary.ID)
//this special deal cause the DescribeSnatEntry can't find the records would be throw "cant find the snatTable error"
if instance.ForwardEntryId == "" {
return nil
}
if instance.ForwardEntryId != "" {
return fmt.Errorf("Forward entry still exist")
}
if err != nil {
// Verify the error is what we want
e, _ := err.(*common.Error)
if !notFoundError(e) {
return err
}
}
}
return nil
}
func testAccCheckForwardEntryExists(n string, snat *ecs.ForwardTableEntrySetType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ForwardEntry ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
instance, err := client.DescribeForwardEntry(rs.Primary.Attributes["forward_table_id"], rs.Primary.ID)
if err != nil {
return err
}
if instance.ForwardEntryId == "" {
return fmt.Errorf("ForwardEntry not found")
}
*snat = instance
return nil
}
}
const testAccForwardEntryConfig = `
provider "alicloud"{
region = "cn-hangzhou"
}
data "alicloud_zones" "default" {
"available_resource_creation"= "VSwitch"
}
resource "alicloud_vpc" "foo" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
resource "alicloud_nat_gateway" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [{
ip_count = 1
bandwidth = 5
zone = "${data.alicloud_zones.default.zones.0.id}"
},{
ip_count = 1
bandwidth = 6
zone = "${data.alicloud_zones.default.zones.0.id}"
}]
depends_on = [
"alicloud_vswitch.foo"]
}
resource "alicloud_forward_entry" "foo"{
forward_table_id = "${alicloud_nat_gateway.foo.forward_table_ids}"
external_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
external_port = "80"
ip_protocol = "tcp"
internal_ip = "172.16.0.3"
internal_port = "8080"
}
resource "alicloud_forward_entry" "foo1"{
forward_table_id = "${alicloud_nat_gateway.foo.forward_table_ids}"
external_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
external_port = "443"
ip_protocol = "udp"
internal_ip = "172.16.0.4"
internal_port = "8080"
}
`
const testAccForwardEntryUpdate = `
provider "alicloud"{
region = "cn-hangzhou"
}
data "alicloud_zones" "default" {
"available_resource_creation"= "VSwitch"
}
resource "alicloud_vpc" "foo" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
resource "alicloud_nat_gateway" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [{
ip_count = 1
bandwidth = 5
zone = "${data.alicloud_zones.default.zones.0.id}"
},{
ip_count = 1
bandwidth = 6
zone = "${data.alicloud_zones.default.zones.0.id}"
}]
depends_on = [
"alicloud_vswitch.foo"]
}
resource "alicloud_forward_entry" "foo"{
forward_table_id = "${alicloud_nat_gateway.foo.forward_table_ids}"
external_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
external_port = "80"
ip_protocol = "tcp"
internal_ip = "172.16.0.3"
internal_port = "8081"
}
resource "alicloud_forward_entry" "foo1"{
forward_table_id = "${alicloud_nat_gateway.foo.forward_table_ids}"
external_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
external_port = "22"
ip_protocol = "udp"
internal_ip = "172.16.0.4"
internal_port = "8080"
}
`

View File

@ -6,11 +6,12 @@ import (
"encoding/base64"
"encoding/json"
"strings"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"strings"
"time"
)
func resourceAliyunInstance() *schema.Resource {
@ -194,19 +195,16 @@ func resourceAliyunInstanceCreate(d *schema.ResourceData, meta interface{}) erro
//d.Set("system_disk_category", d.Get("system_disk_category"))
//d.Set("system_disk_size", d.Get("system_disk_size"))
if err := allocateIpAndBandWidthRelative(d, meta); err != nil {
return fmt.Errorf("allocateIpAndBandWidthRelative err: %#v", err)
}
// 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) {
_, err := conn.AllocatePublicIpAddress(d.Id())
if err != nil {
log.Printf("[DEBUG] AllocatePublicIpAddress for instance got error: %#v", err)
}
}
if err := conn.StartInstance(d.Id()); err != nil {
return fmt.Errorf("Start instance got error: %#v", err)
}
@ -258,11 +256,12 @@ func resourceAliyunRunInstance(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] WaitForInstance %s got error: %#v", ecs.Running, err)
}
if d.Get("allocate_public_ip").(bool) {
_, err := conn.AllocatePublicIpAddress(d.Id())
if err != nil {
log.Printf("[DEBUG] AllocatePublicIpAddress for instance got error: %#v", err)
}
if err := allocateIpAndBandWidthRelative(d, meta); err != nil {
return fmt.Errorf("allocateIpAndBandWidthRelative err: %#v", err)
}
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)
@ -458,30 +457,47 @@ func resourceAliyunInstanceDelete(d *schema.ResourceData, meta interface{}) erro
client := meta.(*AliyunClient)
conn := client.ecsconn
instance, err := client.QueryInstancesById(d.Id())
if err != nil {
if notFoundError(err) {
return nil
}
return fmt.Errorf("Error DescribeInstanceAttribute: %#v", err)
}
if instance.Status != ecs.Stopped {
if err := conn.StopInstance(d.Id(), true); err != nil {
return err
return resource.Retry(5*time.Minute, func() *resource.RetryError {
instance, err := client.QueryInstancesById(d.Id())
if err != nil {
if notFoundError(err) {
return nil
}
}
if err := conn.WaitForInstance(d.Id(), ecs.Stopped, defaultTimeout); err != nil {
return err
if instance.Status != ecs.Stopped {
if err := conn.StopInstance(d.Id(), true); err != nil {
return resource.RetryableError(fmt.Errorf("ECS stop error - trying again."))
}
if err := conn.WaitForInstance(d.Id(), ecs.Stopped, defaultTimeout); err != nil {
return resource.RetryableError(fmt.Errorf("Waiting for ecs stopped timeout - trying again."))
}
}
if err := conn.DeleteInstance(d.Id()); err != nil {
return resource.RetryableError(fmt.Errorf("ECS Instance in use - trying again while it is deleted."))
}
return nil
})
}
func allocateIpAndBandWidthRelative(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AliyunClient).ecsconn
if d.Get("allocate_public_ip").(bool) {
if d.Get("internet_max_bandwidth_out") == 0 {
return fmt.Errorf("Error: if allocate_public_ip is true than the internet_max_bandwidth_out cannot equal zero.")
}
_, err := conn.AllocatePublicIpAddress(d.Id())
if err != nil {
return fmt.Errorf("[DEBUG] AllocatePublicIpAddress for instance got error: %#v", err)
}
}
if err := conn.DeleteInstance(d.Id()); err != nil {
return err
}
return nil
}
func buildAliyunRunInstancesArgs(d *schema.ResourceData, meta interface{}) (*ecs.RunInstanceArgs, error) {
args := &ecs.RunInstanceArgs{
MaxAmount: DEFAULT_INSTANCE_COUNT,
@ -567,7 +583,6 @@ func buildAliyunInstanceArgs(d *schema.ResourceData, meta interface{}) (*ecs.Cre
args.Description = v
}
log.Printf("[DEBUG] SystemDisk is %d", systemDiskSize)
if v := d.Get("internet_charge_type").(string); v != "" {
args.InternetChargeType = common.InternetChargeType(v)
}

View File

@ -8,6 +8,7 @@ import (
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"log"
"strconv"
"strings"
"time"
)
@ -44,6 +45,16 @@ func resourceAliyunNatGateway() *schema.Resource {
Computed: true,
},
"snat_table_ids": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"forward_table_ids": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"bandwidth_packages": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Resource{
@ -60,6 +71,10 @@ func resourceAliyunNatGateway() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"public_ip_addresses": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
},
Required: true,
@ -133,8 +148,16 @@ func resourceAliyunNatGatewayRead(d *schema.ResourceData, meta interface{}) erro
d.Set("name", natGateway.Name)
d.Set("spec", natGateway.Spec)
d.Set("bandwidth_package_ids", strings.Join(natGateway.BandwidthPackageIds.BandwidthPackageId, ","))
d.Set("snat_table_ids", strings.Join(natGateway.SnatTableIds.SnatTableId, ","))
d.Set("forward_table_ids", strings.Join(natGateway.ForwardTableIds.ForwardTableId, ","))
d.Set("description", natGateway.Description)
d.Set("vpc_id", natGateway.VpcId)
bindWidthPackages, err := flattenBandWidthPackages(natGateway.BandwidthPackageIds.BandwidthPackageId, meta, d)
if err != nil {
log.Printf("[ERROR] bindWidthPackages flattenBandWidthPackages failed. natgateway id is %#v", d.Id())
} else {
d.Set("bandwidth_packages", bindWidthPackages)
}
return nil
}
@ -254,7 +277,7 @@ func resourceAliyunNatGatewayDelete(d *schema.ResourceData, meta interface{}) er
}
args := &ecs.DeleteNatGatewayArgs{
RegionId: client.Region,
RegionId: getRegion(d, meta),
NatGatewayId: d.Id(),
}
@ -267,7 +290,7 @@ func resourceAliyunNatGatewayDelete(d *schema.ResourceData, meta interface{}) er
}
describeArgs := &ecs.DescribeNatGatewaysArgs{
RegionId: client.Region,
RegionId: getRegion(d, meta),
NatGatewayId: d.Id(),
}
gw, _, gwErr := conn.DescribeNatGateways(describeArgs)
@ -282,3 +305,69 @@ func resourceAliyunNatGatewayDelete(d *schema.ResourceData, meta interface{}) er
return resource.RetryableError(fmt.Errorf("NatGateway in use - trying again while it is deleted."))
})
}
func flattenBandWidthPackages(bandWidthPackageIds []string, meta interface{}, d *schema.ResourceData) ([]map[string]interface{}, error) {
packageLen := len(bandWidthPackageIds)
result := make([]map[string]interface{}, 0, packageLen)
for i := packageLen - 1; i >= 0; i-- {
packageId := bandWidthPackageIds[i]
packages, err := getPackages(packageId, meta, d)
if err != nil {
log.Printf("[ERROR] NatGateways getPackages failed. packageId is %#v", packageId)
return result, err
}
ipAddress := flattenPackPublicIp(packages.PublicIpAddresses.PublicIpAddresse)
ipCont, ipContErr := strconv.Atoi(packages.IpCount)
bandWidth, bandWidthErr := strconv.Atoi(packages.Bandwidth)
if ipContErr != nil {
log.Printf("[ERROR] NatGateways getPackages failed: ipCont convert error. packageId is %#v", packageId)
return result, ipContErr
}
if bandWidthErr != nil {
log.Printf("[ERROR] NatGateways getPackages failed: bandWidthErr convert error. packageId is %#v", packageId)
return result, bandWidthErr
}
l := map[string]interface{}{
"ip_count": ipCont,
"bandwidth": bandWidth,
"zone": packages.ZoneId,
"public_ip_addresses": ipAddress,
}
result = append(result, l)
}
return result, nil
}
func getPackages(packageId string, meta interface{}, d *schema.ResourceData) (*ecs.DescribeBandwidthPackageType, error) {
client := meta.(*AliyunClient)
conn := client.vpcconn
packages, err := conn.DescribeBandwidthPackages(&ecs.DescribeBandwidthPackagesArgs{
RegionId: getRegion(d, meta),
BandwidthPackageId: packageId,
})
if err != nil {
log.Printf("[ERROR] Describe bandwidth package is failed, BandwidthPackageId Id: %s", packageId)
return nil, err
}
if len(packages) == 0 {
return nil, common.GetClientErrorFromString(InstanceNotfound)
}
return &packages[0], nil
}
func flattenPackPublicIp(publicIpAddressList []ecs.PublicIpAddresseType) string {
var result []string
for _, publicIpAddresses := range publicIpAddressList {
ipAddress := publicIpAddresses.IpAddress
result = append(result, ipAddress)
}
return strings.Join(result, ",")
}

View File

@ -48,6 +48,7 @@ func TestAccAlicloudNatGateway_basic(t *testing.T) {
"alicloud_nat_gateway.foo",
"name",
"test_foo"),
testAccCheckNatgatewayIpAddress("alicloud_nat_gateway.foo", &nat),
),
},
},
@ -96,6 +97,31 @@ func TestAccAlicloudNatGateway_spec(t *testing.T) {
}
func testAccCheckNatgatewayIpAddress(n string, nat *ecs.NatGatewaySetType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No NatGateway ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
natGateway, err := client.DescribeNatGateway(rs.Primary.ID)
if err != nil {
return err
}
if natGateway == nil {
return fmt.Errorf("Natgateway not found")
}
return nil
}
}
func testAccCheckNatGatewayExists(n string, nat *ecs.NatGatewaySetType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
@ -164,7 +190,7 @@ resource "alicloud_vpc" "foo" {
resource "alicloud_vswitch" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
availability_zone = "${data.alicloud_zones.default.zones.2.id}"
}
resource "alicloud_nat_gateway" "foo" {
@ -174,11 +200,19 @@ resource "alicloud_nat_gateway" "foo" {
bandwidth_packages = [{
ip_count = 1
bandwidth = 5
zone = "${data.alicloud_zones.default.zones.0.id}"
zone = "${data.alicloud_zones.default.zones.2.id}"
}, {
ip_count = 2
bandwidth = 10
zone = "${data.alicloud_zones.default.zones.0.id}"
bandwidth = 6
zone = "${data.alicloud_zones.default.zones.2.id}"
}, {
ip_count = 3
bandwidth = 7
zone = "${data.alicloud_zones.default.zones.2.id}"
}, {
ip_count = 1
bandwidth = 8
zone = "${data.alicloud_zones.default.zones.2.id}"
}]
depends_on = [
"alicloud_vswitch.foo"]

View File

@ -74,6 +74,11 @@ func resourceAliyunSecurityGroupRead(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error DescribeSecurityGroupAttribute: %#v", err)
}
if sg == nil {
d.SetId("")
return nil
}
d.Set("name", sg.SecurityGroupName)
d.Set("description", sg.Description)

View File

@ -3,9 +3,10 @@ package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"log"
"strings"
"time"
)
func resourceAliyunSecurityGroupRule() *schema.Resource {
@ -141,7 +142,7 @@ func resourceAliyunSecurityGroupRuleRead(d *schema.ResourceData, meta interface{
}
return fmt.Errorf("Error SecurityGroup rule: %#v", err)
}
log.Printf("[WARN]sg %s, type %s, protocol %s, port %s, rule %#v", sgId, direction, ip_protocol, port_range, rule)
d.Set("type", rule.Direction)
d.Set("ip_protocol", strings.ToLower(string(rule.IpProtocol)))
d.Set("nic_type", rule.NicType)
@ -163,7 +164,7 @@ func resourceAliyunSecurityGroupRuleRead(d *schema.ResourceData, meta interface{
return nil
}
func resourceAliyunSecurityGroupRuleDelete(d *schema.ResourceData, meta interface{}) error {
func deleteSecurityGroupRule(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
ruleType := d.Get("type").(string)
@ -187,6 +188,30 @@ func resourceAliyunSecurityGroupRuleDelete(d *schema.ResourceData, meta interfac
AuthorizeSecurityGroupEgressArgs: *args,
}
return client.RevokeSecurityGroupEgress(revokeArgs)
}
func resourceAliyunSecurityGroupRuleDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
parts := strings.Split(d.Id(), ":")
sgId, direction, ip_protocol, port_range, nic_type := parts[0], parts[1], parts[2], parts[3], parts[4]
return resource.Retry(5*time.Minute, func() *resource.RetryError {
err := deleteSecurityGroupRule(d, meta)
if err != nil {
resource.RetryableError(fmt.Errorf("Security group rule in use - trying again while it is deleted."))
}
_, err = client.DescribeSecurityGroupRule(sgId, direction, nic_type, ip_protocol, port_range)
if err != nil {
if notFoundError(err) {
return nil
}
return resource.NonRetryableError(err)
}
return resource.RetryableError(fmt.Errorf("Security group rule in use - trying again while it is deleted."))
})
}

View File

@ -281,6 +281,11 @@ func resourceAliyunSlbRead(d *schema.ResourceData, meta interface{}) error {
return err
}
if loadBalancer == nil {
d.SetId("")
return nil
}
d.Set("name", loadBalancer.LoadBalancerName)
if loadBalancer.AddressType == slb.InternetAddressType {

View File

@ -64,10 +64,14 @@ func resourceAliyunSlbAttachmentRead(d *schema.ResourceData, meta interface{}) e
if err != nil {
if notFoundError(err) {
d.SetId("")
return fmt.Errorf("Read special SLB Id not found: %#v", err)
return nil
}
return fmt.Errorf("Read special SLB Id not found: %#v", err)
}
return err
if loadBalancer == nil {
d.SetId("")
return nil
}
backendServerType := loadBalancer.BackendServers

View File

@ -0,0 +1,134 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceAliyunSnatEntry() *schema.Resource {
return &schema.Resource{
Create: resourceAliyunSnatEntryCreate,
Read: resourceAliyunSnatEntryRead,
Update: resourceAliyunSnatEntryUpdate,
Delete: resourceAliyunSnatEntryDelete,
Schema: map[string]*schema.Schema{
"snat_table_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"source_vswitch_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"snat_ip": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
}
}
func resourceAliyunSnatEntryCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AliyunClient).vpcconn
args := &ecs.CreateSnatEntryArgs{
RegionId: getRegion(d, meta),
SnatTableId: d.Get("snat_table_id").(string),
SourceVSwitchId: d.Get("source_vswitch_id").(string),
SnatIp: d.Get("snat_ip").(string),
}
resp, err := conn.CreateSnatEntry(args)
if err != nil {
return fmt.Errorf("CreateSnatEntry got error: %#v", err)
}
d.SetId(resp.SnatEntryId)
d.Set("snat_table_id", d.Get("snat_table_id").(string))
return resourceAliyunSnatEntryRead(d, meta)
}
func resourceAliyunSnatEntryRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
snatEntry, err := client.DescribeSnatEntry(d.Get("snat_table_id").(string), d.Id())
if err != nil {
if notFoundError(err) {
return nil
}
return err
}
d.Set("snat_table_id", snatEntry.SnatTableId)
d.Set("source_vswitch_id", snatEntry.SourceVSwitchId)
d.Set("snat_ip", snatEntry.SnatIp)
return nil
}
func resourceAliyunSnatEntryUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
conn := client.vpcconn
snatEntry, err := client.DescribeSnatEntry(d.Get("snat_table_id").(string), d.Id())
if err != nil {
return err
}
d.Partial(true)
attributeUpdate := false
args := &ecs.ModifySnatEntryArgs{
RegionId: getRegion(d, meta),
SnatTableId: snatEntry.SnatTableId,
SnatEntryId: snatEntry.SnatEntryId,
}
if d.HasChange("snat_ip") {
d.SetPartial("snat_ip")
var snat_ip string
if v, ok := d.GetOk("snat_ip"); ok {
snat_ip = v.(string)
} else {
return fmt.Errorf("cann't change snap_ip to empty string")
}
args.SnatIp = snat_ip
attributeUpdate = true
}
if attributeUpdate {
if err := conn.ModifySnatEntry(args); err != nil {
return err
}
}
d.Partial(false)
return resourceAliyunSnatEntryRead(d, meta)
}
func resourceAliyunSnatEntryDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*AliyunClient)
conn := client.vpcconn
snatEntryId := d.Id()
snatTableId := d.Get("snat_table_id").(string)
args := &ecs.DeleteSnatEntryArgs{
RegionId: getRegion(d, meta),
SnatTableId: snatTableId,
SnatEntryId: snatEntryId,
}
if err := conn.DeleteSnatEntry(args); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,180 @@
package alicloud
import (
"fmt"
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"testing"
)
func TestAccAlicloudSnat_basic(t *testing.T) {
var snat ecs.SnatEntrySetType
resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
// module name
IDRefreshName: "alicloud_snat_entry.foo",
Providers: testAccProviders,
CheckDestroy: testAccCheckSnatEntryDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccSnatEntryConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckSnatEntryExists(
"alicloud_snat_entry.foo", &snat),
),
},
resource.TestStep{
Config: testAccSnatEntryUpdate,
Check: resource.ComposeTestCheckFunc(
testAccCheckSnatEntryExists(
"alicloud_snat_entry.foo", &snat),
),
},
},
})
}
func testAccCheckSnatEntryDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*AliyunClient)
for _, rs := range s.RootModule().Resources {
if rs.Type != "alicloud_snat_entry" {
continue
}
// Try to find the Snat entry
instance, err := client.DescribeSnatEntry(rs.Primary.Attributes["snat_table_id"], rs.Primary.ID)
//this special deal cause the DescribeSnatEntry can't find the records would be throw "cant find the snatTable error"
if instance.SnatEntryId == "" {
return nil
}
if instance.SnatEntryId != "" {
return fmt.Errorf("Snat entry still exist")
}
if err != nil {
// Verify the error is what we want
e, _ := err.(*common.Error)
if !notFoundError(e) {
return err
}
}
}
return nil
}
func testAccCheckSnatEntryExists(n string, snat *ecs.SnatEntrySetType) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No SnatEntry ID is set")
}
client := testAccProvider.Meta().(*AliyunClient)
instance, err := client.DescribeSnatEntry(rs.Primary.Attributes["snat_table_id"], rs.Primary.ID)
if err != nil {
return err
}
if instance.SnatEntryId == "" {
return fmt.Errorf("SnatEntry not found")
}
*snat = instance
return nil
}
}
const testAccSnatEntryConfig = `
data "alicloud_zones" "default" {
"available_resource_creation"= "VSwitch"
}
resource "alicloud_vpc" "foo" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${data.alicloud_zones.default.zones.2.id}"
}
resource "alicloud_nat_gateway" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [{
ip_count = 2
bandwidth = 5
zone = "${data.alicloud_zones.default.zones.2.id}"
},{
ip_count = 1
bandwidth = 6
zone = "${data.alicloud_zones.default.zones.2.id}"
}]
depends_on = [
"alicloud_vswitch.foo"]
}
resource "alicloud_snat_entry" "foo"{
snat_table_id = "${alicloud_nat_gateway.foo.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.foo.id}"
snat_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
}
`
const testAccSnatEntryUpdate = `
data "alicloud_zones" "default" {
"available_resource_creation"= "VSwitch"
}
resource "alicloud_vpc" "foo" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "${data.alicloud_zones.default.zones.2.id}"
}
resource "alicloud_nat_gateway" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [{
ip_count = 2
bandwidth = 5
zone = "${data.alicloud_zones.default.zones.2.id}"
},{
ip_count = 1
bandwidth = 6
zone = "${data.alicloud_zones.default.zones.2.id}"
}]
depends_on = [
"alicloud_vswitch.foo"]
}
resource "alicloud_snat_entry" "foo"{
snat_table_id = "${alicloud_nat_gateway.foo.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.foo.id}"
snat_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.1.public_ip_addresses}"
}
`

View File

@ -86,7 +86,7 @@ func resourceAliyunVpcCreate(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("Timeout when WaitForVpcAvailable")
}
return resourceAliyunVpcRead(d, meta)
return resourceAliyunVpcUpdate(d, meta)
}
func resourceAliyunVpcRead(d *schema.ResourceData, meta interface{}) error {
@ -144,7 +144,7 @@ func resourceAliyunVpcUpdate(d *schema.ResourceData, meta interface{}) error {
d.Partial(false)
return nil
return resourceAliyunVpcRead(d, meta)
}
func resourceAliyunVpcDelete(d *schema.ResourceData, meta interface{}) error {

View File

@ -68,7 +68,7 @@ func resourceAliyunSwitchCreate(d *schema.ResourceData, meta interface{}) error
return fmt.Errorf("WaitForVSwitchAvailable got a error: %s", err)
}
return resourceAliyunSwitchRead(d, meta)
return resourceAliyunSwitchUpdate(d, meta)
}
func resourceAliyunSwitchRead(d *schema.ResourceData, meta interface{}) error {
@ -139,7 +139,7 @@ func resourceAliyunSwitchUpdate(d *schema.ResourceData, meta interface{}) error
d.Partial(false)
return nil
return resourceAliyunSwitchRead(d, meta)
}
func resourceAliyunSwitchDelete(d *schema.ResourceData, meta interface{}) error {

View File

@ -131,7 +131,7 @@ func (client *AliyunClient) QueryInstancesById(id string) (instance *ecs.Instanc
}
if len(instances) == 0 {
return nil, common.GetClientErrorFromString(InstanceNotfound)
return nil, GetNotFoundErrorFromString(InstanceNotfound)
}
return &instances[0], nil
@ -244,7 +244,7 @@ func (client *AliyunClient) DescribeSecurityGroupRule(securityGroupId, direction
return &p, nil
}
}
return nil, nil
return nil, GetNotFoundErrorFromString("Security group rule not found")
}

View File

@ -0,0 +1,167 @@
package alicloud
import (
"github.com/denverdino/aliyungo/ess"
)
func (client *AliyunClient) DescribeScalingGroupById(sgId string) (*ess.ScalingGroupItemType, error) {
args := ess.DescribeScalingGroupsArgs{
RegionId: client.Region,
ScalingGroupId: []string{sgId},
}
sgs, _, err := client.essconn.DescribeScalingGroups(&args)
if err != nil {
return nil, err
}
if len(sgs) == 0 {
return nil, GetNotFoundErrorFromString("Scaling group not found")
}
return &sgs[0], nil
}
func (client *AliyunClient) DeleteScalingGroupById(sgId string) error {
args := ess.DeleteScalingGroupArgs{
ScalingGroupId: sgId,
ForceDelete: true,
}
_, err := client.essconn.DeleteScalingGroup(&args)
return err
}
func (client *AliyunClient) DescribeScalingConfigurationById(sgId, configId string) (*ess.ScalingConfigurationItemType, error) {
args := ess.DescribeScalingConfigurationsArgs{
RegionId: client.Region,
ScalingGroupId: sgId,
ScalingConfigurationId: []string{configId},
}
cs, _, err := client.essconn.DescribeScalingConfigurations(&args)
if err != nil {
return nil, err
}
if len(cs) == 0 {
return nil, GetNotFoundErrorFromString("Scaling configuration not found")
}
return &cs[0], nil
}
func (client *AliyunClient) ActiveScalingConfigurationById(sgId, configId string) error {
args := ess.ModifyScalingGroupArgs{
ScalingGroupId: sgId,
ActiveScalingConfigurationId: configId,
}
_, err := client.essconn.ModifyScalingGroup(&args)
return err
}
func (client *AliyunClient) EnableScalingConfigurationById(sgId, configId string, ids []string) error {
args := ess.EnableScalingGroupArgs{
ScalingGroupId: sgId,
ActiveScalingConfigurationId: configId,
}
if len(ids) > 0 {
args.InstanceId = ids
}
_, err := client.essconn.EnableScalingGroup(&args)
return err
}
func (client *AliyunClient) DisableScalingConfigurationById(sgId string) error {
args := ess.DisableScalingGroupArgs{
ScalingGroupId: sgId,
}
_, err := client.essconn.DisableScalingGroup(&args)
return err
}
func (client *AliyunClient) DeleteScalingConfigurationById(sgId, configId string) error {
args := ess.DeleteScalingConfigurationArgs{
ScalingGroupId: sgId,
ScalingConfigurationId: configId,
}
_, err := client.essconn.DeleteScalingConfiguration(&args)
return err
}
// Flattens an array of datadisk into a []map[string]interface{}
func flattenDataDiskMappings(list []ess.DataDiskItemType) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
l := map[string]interface{}{
"size": i.Size,
"category": i.Category,
"snapshot_id": i.SnapshotId,
"device": i.Device,
}
result = append(result, l)
}
return result
}
func (client *AliyunClient) DescribeScalingRuleById(sgId, ruleId string) (*ess.ScalingRuleItemType, error) {
args := ess.DescribeScalingRulesArgs{
RegionId: client.Region,
ScalingGroupId: sgId,
ScalingRuleId: []string{ruleId},
}
cs, _, err := client.essconn.DescribeScalingRules(&args)
if err != nil {
return nil, err
}
if len(cs) == 0 {
return nil, GetNotFoundErrorFromString("Scaling rule not found")
}
return &cs[0], nil
}
func (client *AliyunClient) DeleteScalingRuleById(ruleId string) error {
args := ess.DeleteScalingRuleArgs{
RegionId: client.Region,
ScalingRuleId: ruleId,
}
_, err := client.essconn.DeleteScalingRule(&args)
return err
}
func (client *AliyunClient) DescribeScheduleById(scheduleId string) (*ess.ScheduledTaskItemType, error) {
args := ess.DescribeScheduledTasksArgs{
RegionId: client.Region,
ScheduledTaskId: []string{scheduleId},
}
cs, _, err := client.essconn.DescribeScheduledTasks(&args)
if err != nil {
return nil, err
}
if len(cs) == 0 {
return nil, GetNotFoundErrorFromString("Schedule not found")
}
return &cs[0], nil
}
func (client *AliyunClient) DeleteScheduleById(scheduleId string) error {
args := ess.DeleteScheduledTaskArgs{
RegionId: client.Region,
ScheduledTaskId: scheduleId,
}
_, err := client.essconn.DeleteScheduledTask(&args)
return err
}

View File

@ -6,7 +6,20 @@ import (
"strings"
)
// when getInstance is empty, then throw InstanceNotfound error
//
// _______________ _______________ _______________
// | | ______param______\ | | _____request_____\ | |
// | Business | | Service | | SDK/API |
// | | __________________ | | __________________ | |
// |______________| \ (obj, err) |______________| \ (status, cont) |______________|
// | |
// |A. {instance, nil} |a. {200, content}
// |B. {nil, error} |b. {200, nil}
// |c. {4xx, nil}
//
// The API return 200 for resource not found.
// When getInstance is empty, then throw InstanceNotfound error.
// That the business layer only need to check error.
func (client *AliyunClient) DescribeDBInstanceById(id string) (instance *rds.DBInstanceAttribute, err error) {
arrtArgs := rds.DescribeDBInstancesArgs{
DBInstanceId: id,
@ -19,7 +32,7 @@ func (client *AliyunClient) DescribeDBInstanceById(id string) (instance *rds.DBI
attr := resp.Items.DBInstanceAttribute
if len(attr) <= 0 {
return nil, common.GetClientErrorFromString(InstanceNotfound)
return nil, GetNotFoundErrorFromString("DB instance not found")
}
return &attr[0], nil
@ -164,13 +177,10 @@ func (client *AliyunClient) GetSecurityIps(instanceId string) ([]string, error)
if err != nil {
return nil, err
}
ips := ""
for i, ip := range arr {
if i == 0 {
ips += ip.SecurityIPList
} else {
ips += COMMA_SEPARATED + ip.SecurityIPList
}
var ips, separator string
for _, ip := range arr {
ips += separator + ip.SecurityIPList
separator = COMMA_SEPARATED
}
return strings.Split(ips, COMMA_SEPARATED), nil
}

View File

@ -32,6 +32,7 @@ func (client *AliyunClient) DescribeNatGateway(natGatewayId string) (*ecs.NatGat
}
natGateways, _, err := client.vpcconn.DescribeNatGateways(args)
//fmt.Println("natGateways %#v", natGateways)
if err != nil {
return nil, err
}
@ -64,6 +65,78 @@ func (client *AliyunClient) DescribeVpc(vpcId string) (*ecs.VpcSetType, error) {
return &vpcs[0], nil
}
func (client *AliyunClient) DescribeSnatEntry(snatTableId string, snatEntryId string) (ecs.SnatEntrySetType, error) {
var resultSnat ecs.SnatEntrySetType
args := &ecs.DescribeSnatTableEntriesArgs{
RegionId: client.Region,
SnatTableId: snatTableId,
}
snatEntries, _, err := client.vpcconn.DescribeSnatTableEntries(args)
//this special deal cause the DescribeSnatEntry can't find the records would be throw "cant find the snatTable error"
//so judge the snatEntries length priority
if len(snatEntries) == 0 {
return resultSnat, common.GetClientErrorFromString(InstanceNotfound)
}
if err != nil {
return resultSnat, err
}
findSnat := false
for _, snat := range snatEntries {
if snat.SnatEntryId == snatEntryId {
resultSnat = snat
findSnat = true
}
}
if !findSnat {
return resultSnat, common.GetClientErrorFromString(NotFindSnatEntryBySnatId)
}
return resultSnat, nil
}
func (client *AliyunClient) DescribeForwardEntry(forwardTableId string, forwardEntryId string) (ecs.ForwardTableEntrySetType, error) {
var resultFoward ecs.ForwardTableEntrySetType
args := &ecs.DescribeForwardTableEntriesArgs{
RegionId: client.Region,
ForwardTableId: forwardTableId,
}
forwardEntries, _, err := client.vpcconn.DescribeForwardTableEntries(args)
//this special deal cause the DescribeSnatEntry can't find the records would be throw "cant find the snatTable error"
//so judge the snatEntries length priority
if len(forwardEntries) == 0 {
return resultFoward, common.GetClientErrorFromString(InstanceNotfound)
}
findForward := false
for _, forward := range forwardEntries {
if forward.ForwardEntryId == forwardEntryId {
resultFoward = forward
findForward = true
}
}
if !findForward {
return resultFoward, common.GetClientErrorFromString(NotFindForwardEntryByForwardId)
}
if err != nil {
return resultFoward, err
}
return resultFoward, nil
}
// describe vswitch by param filters
func (client *AliyunClient) QueryVswitches(args *ecs.DescribeVSwitchesArgs) (vswitches []ecs.VSwitchSetType, err error) {
vsws, _, err := client.ecsconn.DescribeVSwitches(args)
@ -130,7 +203,7 @@ func (client *AliyunClient) QueryRouteEntry(routeTableId, cidrBlock, nextHopType
return &e, nil
}
}
return nil, nil
return nil, GetNotFoundErrorFromString("Vpc router entry not found")
}
func (client *AliyunClient) GetVpcIdByVSwitchId(vswitchId string) (vpcId string, err error) {

View File

@ -1,11 +0,0 @@
package alicloud
// Takes the result of flatmap.Expand for an array of strings
// and returns a []string
func expandStringList(configured []interface{}) []string {
vs := make([]string, 0, len(configured))
for _, v := range configured {
vs = append(vs, v.(string))
}
return vs
}

View File

@ -18,7 +18,7 @@ func validateInstancePort(v interface{}, k string) (ws []string, errors []error)
value := v.(int)
if value < 1 || value > 65535 {
errors = append(errors, fmt.Errorf(
"%q must be a valid instance port between 1 and 65535",
"%q must be a valid port between 1 and 65535",
k))
return
}
@ -26,8 +26,8 @@ func validateInstancePort(v interface{}, k string) (ws []string, errors []error)
}
func validateInstanceProtocol(v interface{}, k string) (ws []string, errors []error) {
protocal := v.(string)
if !isProtocalValid(protocal) {
protocol := v.(string)
if !isProtocolValid(protocol) {
errors = append(errors, fmt.Errorf(
"%q is an invalid value. Valid values are either http, https, tcp or udp",
k))
@ -282,9 +282,9 @@ func validateInternetChargeType(v interface{}, k string) (ws []string, errors []
func validateInternetMaxBandWidthOut(v interface{}, k string) (ws []string, errors []error) {
value := v.(int)
if value < 1 || value > 100 {
if value < 0 || value > 100 {
errors = append(errors, fmt.Errorf(
"%q must be a valid internet bandwidth out between 1 and 1000",
"%q must be a valid internet bandwidth out between 0 and 100",
k))
return
}
@ -565,3 +565,14 @@ func validateRegion(v interface{}, k string) (ws []string, errors []error) {
}
return
}
func validateForwardPort(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if value != "any" {
valueConv, err := strconv.Atoi(value)
if err != nil || valueConv < 1 || valueConv > 65535 {
errors = append(errors, fmt.Errorf("%q must be a valid port between 1 and 65535 or any ", k))
}
}
return
}

View File

@ -21,17 +21,17 @@ func TestValidateInstancePort(t *testing.T) {
}
func TestValidateInstanceProtocol(t *testing.T) {
validProtocals := []string{"http", "tcp", "https", "udp"}
for _, v := range validProtocals {
_, errors := validateInstanceProtocol(v, "instance_protocal")
validProtocols := []string{"http", "tcp", "https", "udp"}
for _, v := range validProtocols {
_, errors := validateInstanceProtocol(v, "instance_protocol")
if len(errors) != 0 {
t.Fatalf("%q should be a valid instance protocol: %q", v, errors)
}
}
invalidProtocals := []string{"HTTP", "abc", "ecmp", "dubbo"}
for _, v := range invalidProtocals {
_, errors := validateInstanceProtocol(v, "instance_protocal")
invalidProtocols := []string{"HTTP", "abc", "ecmp", "dubbo"}
for _, v := range invalidProtocols {
_, errors := validateInstanceProtocol(v, "instance_protocol")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid instance protocol", v)
}
@ -353,7 +353,7 @@ func TestValidateInternetMaxBandWidthOut(t *testing.T) {
}
}
invalidInternetMaxBandWidthOut := []int{-2, 0, 101, 123}
invalidInternetMaxBandWidthOut := []int{-2, 101, 123}
for _, v := range invalidInternetMaxBandWidthOut {
_, errors := validateInternetMaxBandWidthOut(v, "internet_max_bandwidth_out")
if len(errors) == 0 {

View File

@ -0,0 +1,17 @@
### ESS scaling configuration Example
The example launches ESS scaling configuration, will create ECS instance automatic by system schedule.
### Get up and running
* Planning phase
terraform plan
* Apply phase
terraform apply
* Destroy
terraform destroy

View File

@ -0,0 +1,38 @@
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "sg" {
name = "${var.security_group_name}"
description = "tf-sg"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.sg.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "scaling" {
min_size = "${var.scaling_min_size}"
max_size = "${var.scaling_max_size}"
scaling_group_name = "tf-scaling"
removal_policies = "${var.removal_policies}"
}
resource "alicloud_ess_scaling_configuration" "config" {
scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}"
enable = "${var.enable}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "${var.ecs_instance_type}"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.sg.id}"
}

View File

@ -0,0 +1,7 @@
output "scaling_group_id" {
value = "${alicloud_ess_scaling_group.scaling.id}"
}
output "configuration_id" {
value = "${alicloud_ess_scaling_configuration.config.id}"
}

View File

@ -0,0 +1,24 @@
variable "security_group_name" {
default = "tf-sg"
}
variable "scaling_min_size" {
default = 1
}
variable "scaling_max_size" {
default = 1
}
variable "enable" {
default = true
}
variable "removal_policies" {
type = "list"
default = ["OldestInstance", "NewestInstance"]
}
variable "ecs_instance_type" {
default = "ecs.s2.large"
}

View File

@ -0,0 +1,17 @@
### ESS scaling schedule Example
The example launches ESS schedule task, which will create ECS by the schedule time.
### Get up and running
* Planning phase
terraform plan
* Apply phase
terraform apply
* Destroy
terraform destroy

View File

@ -0,0 +1,51 @@
data "alicloud_images" "ecs_image" {
most_recent = true
name_regex = "^centos_6\\w{1,5}[64].*"
}
resource "alicloud_security_group" "sg" {
name = "${var.security_group_name}"
description = "tf-sg"
}
resource "alicloud_security_group_rule" "ssh-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "internet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = "${alicloud_security_group.sg.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_ess_scaling_group" "scaling" {
min_size = "${var.scaling_min_size}"
max_size = "${var.scaling_max_size}"
scaling_group_name = "tf-scaling"
removal_policies = "${var.removal_policies}"
}
resource "alicloud_ess_scaling_configuration" "config" {
scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}"
enable = "${var.enable}"
image_id = "${data.alicloud_images.ecs_image.images.0.id}"
instance_type = "${var.ecs_instance_type}"
io_optimized = "optimized"
security_group_id = "${alicloud_security_group.sg.id}"
}
resource "alicloud_ess_scaling_rule" "rule" {
scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}"
adjustment_type = "TotalCapacity"
adjustment_value = "${var.rule_adjust_size}"
cooldown = 60
}
resource "alicloud_ess_schedule" "run" {
scheduled_action = "${alicloud_ess_scaling_rule.rule.ari}"
launch_time = "${var.schedule_launch_time}"
scheduled_task_name = "tf-run"
}

View File

@ -0,0 +1,11 @@
output "scaling_group_id" {
value = "${alicloud_ess_scaling_group.scaling.id}"
}
output "configuration_id" {
value = "${alicloud_ess_scaling_configuration.config.id}"
}
output "configuration_ari" {
value = "${alicloud_ess_scaling_configuration.config.ari}"
}

View File

@ -0,0 +1,32 @@
variable "security_group_name" {
default = "tf-sg"
}
variable "scaling_min_size" {
default = 1
}
variable "scaling_max_size" {
default = 1
}
variable "enable" {
default = true
}
variable "removal_policies" {
type = "list"
default = ["OldestInstance", "NewestInstance"]
}
variable "ecs_instance_type" {
default = "ecs.s2.large"
}
variable "rule_adjust_size" {
default = 3
}
variable "schedule_launch_time" {
default = "2017-04-01T01:59Z"
}

View File

@ -0,0 +1,87 @@
provider "alicloud" {
region = "cn-hangzhou"
}
data "alicloud_instance_types" "1c2g" {
cpu_core_count = 1
memory_size = 2
instance_type_family = "ecs.n1"
}
data "alicloud_zones" "default" {
"available_instance_type"= "${data.alicloud_instance_types.1c2g.instance_types.0.id}"
"available_disk_category"= "${var.disk_category}"
}
resource "alicloud_vpc" "default" {
name = "tf_vpc"
cidr_block = "${var.vpc_cidr}"
}
resource "alicloud_vswitch" "default" {
vpc_id = "${alicloud_vpc.default.id}"
cidr_block = "${var.vswitch_cidr}"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
}
resource "alicloud_nat_gateway" "default" {
vpc_id = "${alicloud_vpc.default.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [{
ip_count = 2
bandwidth = 5
zone = "${data.alicloud_zones.default.zones.0.id}"
}]
depends_on = [
"alicloud_vswitch.default"]
}
resource "alicloud_snat_entry" "default"{
snat_table_id = "${alicloud_nat_gateway.default.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.default.id}"
snat_ip = "${element(split(",", alicloud_nat_gateway.default.bandwidth_packages.0.public_ip_addresses),0)}"
}
resource "alicloud_forward_entry" "default"{
forward_table_id = "${alicloud_nat_gateway.default.forward_table_ids}"
external_ip = "${element(split(",", alicloud_nat_gateway.default.bandwidth_packages.0.public_ip_addresses),1)}"
external_port = "80"
ip_protocol = "tcp"
internal_ip = "${alicloud_instance.default.private_ip}"
internal_port = "8080"
}
resource "alicloud_security_group" "sg" {
name = "tf_sg"
description = "tf_sg"
vpc_id = "${alicloud_vpc.default.id}"
}
resource "alicloud_security_group_rule" "http-in" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "80/80"
priority = 1
security_group_id = "${alicloud_security_group.sg.id}"
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_instance" "default" {
# cn-beijing
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
security_groups = ["${alicloud_security_group.sg.id}"]
vswitch_id = "${alicloud_vswitch.default.id}"
# series II
instance_charge_type = "PostPaid"
instance_type = "${var.instance_type}"
internet_max_bandwidth_out = 0
io_optimized = "${var.io_optimized}"
system_disk_category = "cloud_efficiency"
image_id = "${var.image_id}"
instance_name = "tf_vpc_snat"
}

View File

@ -0,0 +1,7 @@
output "instance_id" {
value = "${alicloud_instance.default.id}"
}
output "bindwidth_package_ip" {
value = "${alicloud_nat_gateway.default.bandwidth_packages.0.public_ip_addresses}"
}

View File

@ -0,0 +1,22 @@
variable "vpc_cidr" {
default = "10.1.0.0/21"
}
variable "vswitch_cidr" {
default = "10.1.1.0/24"
}
variable "rule_policy" {
default = "accept"
}
variable "instance_type" {
default = "ecs.n1.small"
}
variable "image_id" {
default = "ubuntu_140405_64_40G_cloudinit_20161115.vhd"
}
variable "io_optimized" {
default = "optimized"
}
variable "disk_category"{
default = "cloud_efficiency"
}

View File

@ -13,6 +13,14 @@ import (
"github.com/denverdino/aliyungo/util"
)
// RemovalPolicy.N add index to array item
// RemovalPolicy=["a", "b"] => RemovalPolicy.1="a" RemovalPolicy.2="b"
type FlattenArray []string
// string contains underline which will be replaced with dot
// SystemDisk_Category => SystemDisk.Category
type UnderlineString string
// A Client represents a client of ECS services
type Client struct {
AccessKeyId string //Access Key Id
@ -167,6 +175,75 @@ func (client *Client) Invoke(action string, args interface{}, response interface
return nil
}
// Invoke sends the raw HTTP request for ECS services
func (client *Client) InvokeByFlattenMethod(action string, args interface{}, response interface{}) error {
request := Request{}
request.init(client.version, action, client.AccessKeyId)
query := util.ConvertToQueryValues(request)
util.SetQueryValueByFlattenMethod(args, &query)
// Sign request
signature := util.CreateSignatureForRequest(ECSRequestMethod, &query, client.AccessKeySecret)
// Generate the request URL
requestURL := client.endpoint + "?" + query.Encode() + "&Signature=" + url.QueryEscape(signature)
httpReq, err := http.NewRequest(ECSRequestMethod, requestURL, nil)
if err != nil {
return GetClientError(err)
}
// TODO move to util and add build val flag
httpReq.Header.Set("X-SDK-Client", `AliyunGO/`+Version+client.businessInfo)
t0 := time.Now()
httpResp, err := client.httpClient.Do(httpReq)
t1 := time.Now()
if err != nil {
return GetClientError(err)
}
statusCode := httpResp.StatusCode
if client.debug {
log.Printf("Invoke %s %s %d (%v)", ECSRequestMethod, requestURL, statusCode, t1.Sub(t0))
}
defer httpResp.Body.Close()
body, err := ioutil.ReadAll(httpResp.Body)
if err != nil {
return GetClientError(err)
}
if client.debug {
var prettyJSON bytes.Buffer
err = json.Indent(&prettyJSON, body, "", " ")
log.Println(string(prettyJSON.Bytes()))
}
if statusCode >= 400 && statusCode <= 599 {
errorResponse := ErrorResponse{}
err = json.Unmarshal(body, &errorResponse)
ecsError := &Error{
ErrorResponse: errorResponse,
StatusCode: statusCode,
}
return ecsError
}
err = json.Unmarshal(body, response)
//log.Printf("%++v", response)
if err != nil {
return GetClientError(err)
}
return nil
}
// Invoke sends the raw HTTP request for ECS services
//改进了一下上面那个方法可以使用各种Http方法
//2017.1.30 增加了一个path参数用来拓展访问的地址

View File

@ -32,7 +32,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Jaq</ProductName><DomainName>jaq.aliyuncs.com</DomainName></Product>
<Product><ProductName>HPC</ProductName><DomainName>hpc.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
@ -63,11 +62,9 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>M-kvstore</ProductName><DomainName>m-kvstore.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>HighDDos</ProductName><DomainName>yd-highddos-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CmsSiteMonitor</ProductName><DomainName>sitemonitor.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>BatchCompute</ProductName><DomainName>batchCompute.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Drds</ProductName><DomainName>drds.aliyuncs.com</DomainName></Product>
@ -127,7 +124,7 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Jaq</ProductName><DomainName>jaq.aliyuncs.com</DomainName></Product>
<Product><ProductName>CS</ProductName><DomainName>cs.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hongkong.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
@ -158,11 +155,11 @@
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>Bss</ProductName><DomainName>bss.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ubsms</ProductName><DomainName>ubsms.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hongkong.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>CmsSiteMonitor</ProductName><DomainName>sitemonitor.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ace</ProductName><DomainName>ace.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hongkong.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Acs</ProductName><DomainName>acs.aliyun-inc.com</DomainName></Product>
@ -235,7 +232,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Drds</ProductName><DomainName>drds.aliyuncs.com</DomainName></Product>
<Product><ProductName>HPC</ProductName><DomainName>hpc.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
@ -265,9 +261,8 @@
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>Bss</ProductName><DomainName>bss.aliyuncs.com</DomainName></Product>
<Product><ProductName>M-kvstore</ProductName><DomainName>m-kvstore.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ace</ProductName><DomainName>ace.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-qingdao.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Httpdns</ProductName><DomainName>httpdns-api.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
@ -330,6 +325,7 @@
<Endpoint name="cn-shanghai">
<RegionIds><RegionId>cn-shanghai</RegionId></RegionIds>
<Products>
<Product><ProductName>ARMS</ProductName><DomainName>arms.cn-shanghai.aliyuncs.com</DomainName></Product>
<Product><ProductName>Risk</ProductName><DomainName>risk-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>COS</ProductName><DomainName>cos.aliyuncs.com</DomainName></Product>
<Product><ProductName>HPC</ProductName><DomainName>hpc.aliyuncs.com</DomainName></Product>
@ -371,11 +367,11 @@
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>M-kvstore</ProductName><DomainName>m-kvstore.aliyuncs.com</DomainName></Product>
<Product><ProductName>Apigateway</ProductName><DomainName>apigateway.cn-shanghai.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-shanghai.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Vpc</ProductName><DomainName>vpc.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ace</ProductName><DomainName>ace.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-shanghai.aliyuncs.com</DomainName></Product>
<Product><ProductName>Dds</ProductName><DomainName>mongodb.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Acs</ProductName><DomainName>acs.aliyun-inc.com</DomainName></Product>
@ -403,6 +399,7 @@
<Product><ProductName>Ess</ProductName><DomainName>ess.aliyuncs.com</DomainName></Product>
<Product><ProductName>Oss</ProductName><DomainName>oss-cn-shanghai.aliyuncs.com</DomainName></Product>
<Product><ProductName>YundunDdos</ProductName><DomainName>inner-yundun-ddos.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>vod</ProductName><DomainName>vod.cn-shanghai.aliyuncs.com</DomainName></Product>
</Products>
</Endpoint>
<Endpoint name="cn-shenzhen-inner">
@ -419,7 +416,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sales</ProductName><DomainName>sales.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>HPC</ProductName><DomainName>hpc.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
@ -447,10 +443,9 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>M-kvstore</ProductName><DomainName>m-kvstore.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ace</ProductName><DomainName>ace.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-shenzhen.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Httpdns</ProductName><DomainName>httpdns-api.aliyuncs.com</DomainName></Product>
<Product><ProductName>Green</ProductName><DomainName>green.aliyuncs.com</DomainName></Product>
@ -504,7 +499,6 @@
<Product><ProductName>Jaq</ProductName><DomainName>jaq.aliyuncs.com</DomainName></Product>
<Product><ProductName>Push</ProductName><DomainName>cloudpush.aliyuncs.com</DomainName></Product>
<Product><ProductName>Alidns</ProductName><DomainName>alidns.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
@ -534,11 +528,10 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ubsms</ProductName><DomainName>ubsms.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>HighDDos</ProductName><DomainName>yd-highddos-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CmsSiteMonitor</ProductName><DomainName>sitemonitor.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.us-west-1.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Acs</ProductName><DomainName>acs.aliyun-inc.com</DomainName></Product>
<Product><ProductName>Httpdns</ProductName><DomainName>httpdns-api.aliyuncs.com</DomainName></Product>
@ -579,7 +572,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Drds</ProductName><DomainName>drds.aliyuncs.com</DomainName></Product>
<Product><ProductName>HPC</ProductName><DomainName>hpc.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
@ -610,10 +602,9 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ubsms</ProductName><DomainName>ubsms.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>HighDDos</ProductName><DomainName>yd-highddos-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-shanghai.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Httpdns</ProductName><DomainName>httpdns-api.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
@ -652,6 +643,7 @@
<Endpoint name="cn-hangzhou">
<RegionIds><RegionId>cn-hangzhou</RegionId></RegionIds>
<Products>
<Product><ProductName>ARMS</ProductName><DomainName>arms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CS</ProductName><DomainName>cs.aliyuncs.com</DomainName></Product>
<Product><ProductName>COS</ProductName><DomainName>cos.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ess</ProductName><DomainName>ess.aliyuncs.com</DomainName></Product>
@ -743,7 +735,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Drds</ProductName><DomainName>drds.aliyuncs.com</DomainName></Product>
<Product><ProductName>CS</ProductName><DomainName>cs.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
@ -774,10 +765,9 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ubsms</ProductName><DomainName>ubsms.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-beijing.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Httpdns</ProductName><DomainName>httpdns-api.aliyuncs.com</DomainName></Product>
@ -819,6 +809,7 @@
<Endpoint name="cn-shenzhen">
<RegionIds><RegionId>cn-shenzhen</RegionId></RegionIds>
<Products>
<Product><ProductName>ARMS</ProductName><DomainName>arms.cn-shenzhen.aliyuncs.com</DomainName></Product>
<Product><ProductName>CS</ProductName><DomainName>cs.aliyuncs.com</DomainName></Product>
<Product><ProductName>COS</ProductName><DomainName>cos.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ons</ProductName><DomainName>ons.aliyuncs.com</DomainName></Product>
@ -859,7 +850,7 @@
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Vpc</ProductName><DomainName>vpc.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-shenzhen.aliyuncs.com</DomainName></Product>
<Product><ProductName>Oas</ProductName><DomainName>cn-shenzhen.oas.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Acs</ProductName><DomainName>acs.aliyun-inc.com</DomainName></Product>
@ -908,7 +899,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Jaq</ProductName><DomainName>jaq.aliyuncs.com</DomainName></Product>
<Product><ProductName>Dts</ProductName><DomainName>dts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ess</ProductName><DomainName>ess.aliyuncs.com</DomainName></Product>
<Product><ProductName>R-kvstore</ProductName><DomainName>r-kvstore-cn-hangzhou.aliyuncs.com</DomainName></Product>
@ -937,7 +927,7 @@
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-qingdao.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-qingdao.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Acs</ProductName><DomainName>acs.aliyun-inc.com</DomainName></Product>
@ -1003,6 +993,7 @@
<Endpoint name="cn-beijing">
<RegionIds><RegionId>cn-beijing</RegionId></RegionIds>
<Products>
<Product><ProductName>ARMS</ProductName><DomainName>arms.cn-beijing.aliyuncs.com</DomainName></Product>
<Product><ProductName>CS</ProductName><DomainName>cs.aliyuncs.com</DomainName></Product>
<Product><ProductName>COS</ProductName><DomainName>cos.aliyuncs.com</DomainName></Product>
<Product><ProductName>Jaq</ProductName><DomainName>jaq.aliyuncs.com</DomainName></Product>
@ -1046,12 +1037,12 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>M-kvstore</ProductName><DomainName>m-kvstore.aliyuncs.com</DomainName></Product>
<Product><ProductName>Apigateway</ProductName><DomainName>apigateway.cn-beijing.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-beijing.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-beijing.aliyuncs.com</DomainName></Product>
<Product><ProductName>HighDDos</ProductName><DomainName>yd-highddos-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CmsSiteMonitor</ProductName><DomainName>sitemonitor.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ace</ProductName><DomainName>ace.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-beijing.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Acs</ProductName><DomainName>acs.aliyun-inc.com</DomainName></Product>
<Product><ProductName>Httpdns</ProductName><DomainName>httpdns-api.aliyuncs.com</DomainName></Product>
@ -1077,6 +1068,7 @@
<Product><ProductName>Yundun</ProductName><DomainName>yundun-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Cdn</ProductName><DomainName>cdn.aliyuncs.com</DomainName></Product>
<Product><ProductName>YundunDdos</ProductName><DomainName>inner-yundun-ddos.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>vod</ProductName><DomainName>vod.cn-beijing.aliyuncs.com</DomainName></Product>
</Products>
</Endpoint>
<Endpoint name="cn-hangzhou-d">
@ -1092,7 +1084,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sales</ProductName><DomainName>sales.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Dts</ProductName><DomainName>dts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
@ -1122,7 +1113,6 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ubsms</ProductName><DomainName>ubsms.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
@ -1180,7 +1170,6 @@
<Product><ProductName>Sms</ProductName><DomainName>sms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Jaq</ProductName><DomainName>jaq.aliyuncs.com</DomainName></Product>
<Product><ProductName>Dts</ProductName><DomainName>dts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Kms</ProductName><DomainName>kms.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location</ProductName><DomainName>location.aliyuncs.com</DomainName></Product>
<Product><ProductName>Msg</ProductName><DomainName>msg-inner.aliyuncs.com</DomainName></Product>
<Product><ProductName>ChargingService</ProductName><DomainName>chargingservice.aliyuncs.com</DomainName></Product>
@ -1210,7 +1199,6 @@
<Product><ProductName>PTS</ProductName><DomainName>pts.aliyuncs.com</DomainName></Product>
<Product><ProductName>Qualitycheck</ProductName><DomainName>qualitycheck.aliyuncs.com</DomainName></Product>
<Product><ProductName>M-kvstore</ProductName><DomainName>m-kvstore.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Rds</ProductName><DomainName>rds.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
@ -1304,11 +1292,11 @@
<Product><ProductName>Bss</ProductName><DomainName>bss.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ubsms</ProductName><DomainName>ubsms.aliyuncs.com</DomainName></Product>
<Product><ProductName>Apigateway</ProductName><DomainName>apigateway.ap-southeast-1.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>CloudAPI</ProductName><DomainName>apigateway.ap-southeast-1.aliyuncs.com</DomainName></Product>
<Product><ProductName>Sts</ProductName><DomainName>sts.aliyuncs.com</DomainName></Product>
<Product><ProductName>CmsSiteMonitor</ProductName><DomainName>sitemonitor.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ace</ProductName><DomainName>ace.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Mts</ProductName><DomainName>mts.ap-southeast-1.aliyuncs.com</DomainName></Product>
<Product><ProductName>CF</ProductName><DomainName>cf.aliyuncs.com</DomainName></Product>
<Product><ProductName>Crm</ProductName><DomainName>crm-cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Location-inner</ProductName><DomainName>location-inner.aliyuncs.com</DomainName></Product>
@ -1348,4 +1336,14 @@
<Product><ProductName>Slb</ProductName><DomainName>slb.eu-central-1.aliyuncs.com</DomainName></Product>
</Products>
</Endpoint>
</Endpoints>
<Endpoint name="cn-zhangjiakou">
<RegionIds><RegionId>cn-zhangjiakou</RegionId></RegionIds>
<Products>
<Product><ProductName>Rds</ProductName><DomainName>rds.cn-zhangjiakou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Ecs</ProductName><DomainName>ecs.cn-zhangjiakou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Vpc</ProductName><DomainName>vpc.cn-zhangjiakou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Cms</ProductName><DomainName>metrics.cn-hangzhou.aliyuncs.com</DomainName></Product>
<Product><ProductName>Slb</ProductName><DomainName>slb.cn-zhangjiakou.aliyuncs.com</DomainName></Product>
</Products>
</Endpoint>
</Endpoints>

View File

@ -0,0 +1,104 @@
package ecs
import "github.com/denverdino/aliyungo/common"
type CreateForwardEntryArgs struct {
RegionId common.Region
ForwardTableId string
ExternalIp string
ExternalPort string
IpProtocol string
InternalIp string
InternalPort string
}
type CreateForwardEntryResponse struct {
common.Response
ForwardEntryId string
}
type DescribeForwardTableEntriesArgs struct {
RegionId common.Region
ForwardTableId string
common.Pagination
}
type ForwardTableEntrySetType struct {
RegionId common.Region
ExternalIp string
ExternalPort string
ForwardEntryId string
ForwardTableId string
InternalIp string
InternalPort string
IpProtocol string
Status string
}
type DescribeForwardTableEntriesResponse struct {
common.Response
common.PaginationResult
ForwardTableEntries struct {
ForwardTableEntry []ForwardTableEntrySetType
}
}
type ModifyForwardEntryArgs struct {
RegionId common.Region
ForwardTableId string
ForwardEntryId string
ExternalIp string
IpProtocol string
ExternalPort string
InternalIp string
InternalPort string
}
type ModifyForwardEntryResponse struct {
common.Response
}
type DeleteForwardEntryArgs struct {
RegionId common.Region
ForwardTableId string
ForwardEntryId string
}
type DeleteForwardEntryResponse struct {
common.Response
}
func (client *Client) CreateForwardEntry(args *CreateForwardEntryArgs) (resp *CreateForwardEntryResponse, err error) {
response := CreateForwardEntryResponse{}
err = client.Invoke("CreateForwardEntry", args, &response)
if err != nil {
return nil, err
}
return &response, err
}
func (client *Client) DescribeForwardTableEntries(args *DescribeForwardTableEntriesArgs) (forwardTableEntries []ForwardTableEntrySetType,
pagination *common.PaginationResult, err error) {
args.Validate()
response := DescribeForwardTableEntriesResponse{}
err = client.Invoke("DescribeForwardTableEntries", args, &response)
if err != nil {
return nil, nil, err
}
return response.ForwardTableEntries.ForwardTableEntry, &response.PaginationResult, nil
}
func (client *Client) ModifyForwardEntry(args *ModifyForwardEntryArgs) error {
response := ModifyForwardEntryResponse{}
return client.Invoke("ModifyForwardEntry", args, &response)
}
func (client *Client) DeleteForwardEntry(args *DeleteForwardEntryArgs) error {
response := DeleteForwardEntryResponse{}
err := client.Invoke("DeleteForwardEntry", args, &response)
return err
}

View File

@ -79,6 +79,7 @@ type VpcSetType struct {
CidrBlock string
VRouterId string
Description string
IsDefault bool
CreationTime util.ISO6801Time
}

View File

@ -77,6 +77,7 @@ type VSwitchSetType struct {
AvailableIpAddressCount int
Description string
VSwitchName string
IsDefault bool
CreationTime util.ISO6801Time
}

48
vendor/github.com/denverdino/aliyungo/ess/client.go generated vendored Normal file
View File

@ -0,0 +1,48 @@
package ess
import (
"github.com/denverdino/aliyungo/common"
"os"
)
type Client struct {
common.Client
}
const (
// ESSDefaultEndpoint is the default API endpoint of ESS services
ESSDefaultEndpoint = "https://ess.aliyuncs.com"
ESSAPIVersion = "2014-08-28"
ESSServiceCode = "ess"
)
// NewClient creates a new instance of RDS client
func NewClient(accessKeyId, accessKeySecret string) *Client {
endpoint := os.Getenv("ESS_ENDPOINT")
if endpoint == "" {
endpoint = ESSDefaultEndpoint
}
return NewClientWithEndpoint(endpoint, accessKeyId, accessKeySecret)
}
func NewClientWithEndpoint(endpoint string, accessKeyId, accessKeySecret string) *Client {
client := &Client{}
client.Init(endpoint, ESSAPIVersion, accessKeyId, accessKeySecret)
return client
}
func NewESSClient(accessKeyId, accessKeySecret string, regionID common.Region) *Client {
endpoint := os.Getenv("ESS_ENDPOINT")
if endpoint == "" {
endpoint = ESSDefaultEndpoint
}
return NewClientWithRegion(endpoint, accessKeyId, accessKeySecret, regionID)
}
func NewClientWithRegion(endpoint string, accessKeyId, accessKeySecret string, regionID common.Region) *Client {
client := &Client{}
client.NewInit(endpoint, ESSAPIVersion, accessKeyId, accessKeySecret, ESSServiceCode, regionID)
return client
}

View File

@ -0,0 +1,127 @@
package ess
import (
"github.com/denverdino/aliyungo/common"
"github.com/denverdino/aliyungo/ecs"
)
type CreateScalingConfigurationArgs struct {
ScalingGroupId string
ImageId string
InstanceType string
IoOptimized ecs.IoOptimized
SecurityGroupId string
ScalingConfigurationName string
InternetChargeType common.InternetChargeType
InternetMaxBandwidthIn int
InternetMaxBandwidthOut int
SystemDisk_Category common.UnderlineString
SystemDisk_Size common.UnderlineString
DataDisk []DataDiskType
}
type DataDiskType struct {
Category string
SnapshotId string
Device string
Size int
}
type CreateScalingConfigurationResponse struct {
ScalingConfigurationId string
common.Response
}
// CreateScalingConfiguration create scaling configuration
//
// You can read doc at https://help.aliyun.com/document_detail/25944.html?spm=5176.doc25942.6.625.KcE5ir
func (client *Client) CreateScalingConfiguration(args *CreateScalingConfigurationArgs) (resp *CreateScalingConfigurationResponse, err error) {
response := CreateScalingConfigurationResponse{}
err = client.InvokeByFlattenMethod("CreateScalingConfiguration", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type DescribeScalingConfigurationsArgs struct {
RegionId common.Region
ScalingGroupId string
ScalingConfigurationId common.FlattenArray
ScalingConfigurationName common.FlattenArray
common.Pagination
}
type DescribeScalingConfigurationsResponse struct {
common.Response
common.PaginationResult
ScalingConfigurations struct {
ScalingConfiguration []ScalingConfigurationItemType
}
}
type ScalingConfigurationItemType struct {
ScalingConfigurationId string
ScalingConfigurationName string
ScalingGroupId string
ImageId string
InstanceType string
IoOptimized string
SecurityGroupId string
InternetChargeType string
LifecycleState LifecycleState
CreationTime string
InternetMaxBandwidthIn int
InternetMaxBandwidthOut int
SystemDiskCategory string
DataDisks struct {
DataDisk []DataDiskItemType
}
}
type DataDiskItemType struct {
Size int
Category string
SnapshotId string
Device string
}
// DescribeScalingConfigurations describes scaling configuration
//
// You can read doc at https://help.aliyun.com/document_detail/25945.html?spm=5176.doc25944.6.626.knG0zz
func (client *Client) DescribeScalingConfigurations(args *DescribeScalingConfigurationsArgs) (configs []ScalingConfigurationItemType, pagination *common.PaginationResult, err error) {
args.Validate()
response := DescribeScalingConfigurationsResponse{}
err = client.InvokeByFlattenMethod("DescribeScalingConfigurations", args, &response)
if err == nil {
return response.ScalingConfigurations.ScalingConfiguration, &response.PaginationResult, nil
}
return nil, nil, err
}
type DeleteScalingConfigurationArgs struct {
ScalingConfigurationId string
ScalingGroupId string
ImageId string
}
type DeleteScalingConfigurationResponse struct {
common.Response
}
// DeleteScalingConfiguration delete scaling configuration
//
// You can read doc at https://help.aliyun.com/document_detail/25946.html?spm=5176.doc25944.6.627.MjkuuL
func (client *Client) DeleteScalingConfiguration(args *DeleteScalingConfigurationArgs) (resp *DeleteScalingConfigurationResponse, err error) {
response := DeleteScalingConfigurationResponse{}
err = client.InvokeByFlattenMethod("DeleteScalingConfiguration", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}

242
vendor/github.com/denverdino/aliyungo/ess/group.go generated vendored Normal file
View File

@ -0,0 +1,242 @@
package ess
import "github.com/denverdino/aliyungo/common"
type LifecycleState string
const (
Active = LifecycleState("Active")
Inacitve = LifecycleState("Inacitve")
Deleting = LifecycleState("Deleting")
InService = LifecycleState("InService")
Pending = LifecycleState("Pending")
Removing = LifecycleState("Removing")
)
type CreateScalingGroupArgs struct {
RegionId common.Region
ScalingGroupName string
LoadBalancerId string
VpcId string
VSwitchId string
MaxSize int
MinSize int
DefaultCooldown int
RemovalPolicy common.FlattenArray
DBInstanceId common.FlattenArray
}
type CreateScalingGroupResponse struct {
common.Response
ScalingGroupId string
}
// CreateScalingGroup create scaling group
//
// You can read doc at https://help.aliyun.com/document_detail/25936.html?spm=5176.doc25940.6.617.vm6LXF
func (client *Client) CreateScalingGroup(args *CreateScalingGroupArgs) (resp *CreateScalingGroupResponse, err error) {
response := CreateScalingGroupResponse{}
err = client.InvokeByFlattenMethod("CreateScalingGroup", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type ModifyScalingGroupArgs struct {
ScalingGroupId string
ScalingGroupName string
ActiveScalingConfigurationId string
MinSize int
MaxSize int
DefaultCooldown int
RemovalPolicy common.FlattenArray
}
type ModifyScalingGroupResponse struct {
common.Response
}
// ModifyScalingGroup modify scaling group
//
// You can read doc at https://help.aliyun.com/document_detail/25937.html?spm=5176.doc25936.6.618.iwDcXT
func (client *Client) ModifyScalingGroup(args *ModifyScalingGroupArgs) (resp *ModifyScalingGroupResponse, err error) {
response := ModifyScalingGroupResponse{}
err = client.InvokeByFlattenMethod("ModifyScalingGroup", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type DescribeScalingGroupsArgs struct {
RegionId common.Region
ScalingGroupId common.FlattenArray
ScalingGroupName common.FlattenArray
common.Pagination
}
type DescribeInstancesResponse struct {
common.Response
common.PaginationResult
ScalingGroups struct {
ScalingGroup []ScalingGroupItemType
}
}
type ScalingGroupItemType struct {
ScalingGroupId string
ScalingGroupName string
ActiveScalingConfigurationId string
RegionId string
LoadBalancerId string
VSwitchId string
CreationTime string
LifecycleState LifecycleState
MinSize int
MaxSize int
DefaultCooldown int
TotalCapacity int
ActiveCapacity int
PendingCapacity int
RemovingCapacity int
RemovalPolicies RemovalPolicySetType
DBInstanceIds DBInstanceIdSetType
}
type RemovalPolicySetType struct {
RemovalPolicy []string
}
type DBInstanceIdSetType struct {
DBInstanceId []string
}
// DescribeScalingGroups describes scaling groups
//
// You can read doc at https://help.aliyun.com/document_detail/25938.html?spm=5176.doc25937.6.619.sUUOT7
func (client *Client) DescribeScalingGroups(args *DescribeScalingGroupsArgs) (groups []ScalingGroupItemType, pagination *common.PaginationResult, err error) {
args.Validate()
response := DescribeInstancesResponse{}
err = client.InvokeByFlattenMethod("DescribeScalingGroups", args, &response)
if err == nil {
return response.ScalingGroups.ScalingGroup, &response.PaginationResult, nil
}
return nil, nil, err
}
type DescribeScalingInstancesArgs struct {
RegionId common.Region
ScalingGroupId string
ScalingConfigurationId string
HealthStatus string
CreationType string
LifecycleState LifecycleState
InstanceId common.FlattenArray
common.Pagination
}
type DescribeScalingInstancesResponse struct {
common.Response
common.PaginationResult
ScalingInstances struct {
ScalingInstance []ScalingInstanceItemType
}
}
type ScalingInstanceItemType struct {
InstanceId string
ScalingGroupId string
ScalingConfigurationId string
HealthStatus string
CreationTime string
CreationType string
LifecycleState LifecycleState
}
// DescribeScalingInstances describes scaling instances
//
// You can read doc at https://help.aliyun.com/document_detail/25942.html?spm=5176.doc25941.6.623.2xA0Uj
func (client *Client) DescribeScalingInstances(args *DescribeScalingInstancesArgs) (instances []ScalingInstanceItemType, pagination *common.PaginationResult, err error) {
args.Validate()
response := DescribeScalingInstancesResponse{}
err = client.InvokeByFlattenMethod("DescribeScalingInstances", args, &response)
if err == nil {
return response.ScalingInstances.ScalingInstance, &response.PaginationResult, nil
}
return nil, nil, err
}
type EnableScalingGroupArgs struct {
ScalingGroupId string
ActiveScalingConfigurationId string
InstanceId common.FlattenArray
}
type EnableScalingGroupResponse struct {
common.Response
}
// EnableScalingGroup enable scaling group
//
// You can read doc at https://help.aliyun.com/document_detail/25939.html?spm=5176.doc25938.6.620.JiJhkx
func (client *Client) EnableScalingGroup(args *EnableScalingGroupArgs) (resp *EnableScalingGroupResponse, err error) {
response := EnableScalingGroupResponse{}
err = client.InvokeByFlattenMethod("EnableScalingGroup", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type DisableScalingGroupArgs struct {
ScalingGroupId string
}
type DisableScalingGroupResponse struct {
common.Response
}
// DisableScalingGroup disable scaling group
//
// You can read doc at https://help.aliyun.com/document_detail/25940.html?spm=5176.doc25939.6.621.M8GuuY
func (client *Client) DisableScalingGroup(args *DisableScalingGroupArgs) (resp *DisableScalingGroupResponse, err error) {
response := DisableScalingGroupResponse{}
err = client.InvokeByFlattenMethod("DisableScalingGroup", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type DeleteScalingGroupArgs struct {
ScalingGroupId string
ForceDelete bool
}
type DeleteScalingGroupResponse struct {
common.Response
}
// DeleteScalingGroup delete scaling group
//
// You can read doc at https://help.aliyun.com/document_detail/25941.html?spm=5176.doc25940.6.622.mRBCuw
func (client *Client) DeleteScalingGroup(args *DeleteScalingGroupArgs) (resp *DeleteScalingGroupResponse, err error) {
response := DeleteScalingGroupResponse{}
err = client.InvokeByFlattenMethod("DeleteScalingGroup", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}

130
vendor/github.com/denverdino/aliyungo/ess/rule.go generated vendored Normal file
View File

@ -0,0 +1,130 @@
package ess
import "github.com/denverdino/aliyungo/common"
type AdjustmentType string
const (
QuantityChangeInCapacity = AdjustmentType("QuantityChangeInCapacity")
PercentChangeInCapacity = AdjustmentType("PercentChangeInCapacity")
TotalCapacity = AdjustmentType("TotalCapacity")
)
type CreateScalingRuleArgs struct {
RegionId common.Region
ScalingGroupId string
AdjustmentType AdjustmentType
AdjustmentValue int
Cooldown int
ScalingRuleName string
}
type CreateScalingRuleResponse struct {
common.Response
ScalingRuleId string
ScalingRuleAri string
}
// CreateScalingRule create scaling rule
//
// You can read doc at https://help.aliyun.com/document_detail/25948.html?spm=5176.doc25944.6.629.FLkNnj
func (client *Client) CreateScalingRule(args *CreateScalingRuleArgs) (resp *CreateScalingRuleResponse, err error) {
response := CreateScalingRuleResponse{}
err = client.Invoke("CreateScalingRule", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type ModifyScalingRuleArgs struct {
RegionId common.Region
ScalingRuleId string
AdjustmentType AdjustmentType
AdjustmentValue int
Cooldown int
ScalingRuleName string
}
type ModifyScalingRuleResponse struct {
common.Response
}
// ModifyScalingRule modify scaling rule
//
// You can read doc at https://help.aliyun.com/document_detail/25949.html?spm=5176.doc25948.6.630.HGN1va
func (client *Client) ModifyScalingRule(args *ModifyScalingRuleArgs) (resp *ModifyScalingRuleResponse, err error) {
response := ModifyScalingRuleResponse{}
err = client.Invoke("ModifyScalingRule", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type DescribeScalingRulesArgs struct {
common.Pagination
RegionId common.Region
ScalingGroupId string
ScalingRuleId common.FlattenArray
ScalingRuleName common.FlattenArray
ScalingRuleAri common.FlattenArray
}
type DescribeScalingRulesResponse struct {
common.Response
common.PaginationResult
ScalingRules struct {
ScalingRule []ScalingRuleItemType
}
}
type ScalingRuleItemType struct {
ScalingRuleId string
ScalingGroupId string
ScalingRuleName string
AdjustmentType string
ScalingRuleAri string
Cooldown int
AdjustmentValue int
}
// DescribeScalingRules describes scaling rules
//
// You can read doc at https://help.aliyun.com/document_detail/25950.html?spm=5176.doc25949.6.631.RwPguo
func (client *Client) DescribeScalingRules(args *DescribeScalingRulesArgs) (configs []ScalingRuleItemType, pagination *common.PaginationResult, err error) {
args.Validate()
response := DescribeScalingRulesResponse{}
err = client.InvokeByFlattenMethod("DescribeScalingRules", args, &response)
if err == nil {
return response.ScalingRules.ScalingRule, &response.PaginationResult, nil
}
return nil, nil, err
}
type DeleteScalingRuleArgs struct {
RegionId common.Region
ScalingRuleId string
}
type DeleteScalingRuleResponse struct {
common.Response
}
// DeleteScalingRule delete scaling rule
//
// You can read doc at https://help.aliyun.com/document_detail/25951.html?spm=5176.doc25950.6.632.HbPLMZ
func (client *Client) DeleteScalingRule(args *DeleteScalingRuleArgs) (resp *DeleteScalingRuleResponse, err error) {
response := DeleteScalingRuleResponse{}
err = client.InvokeByFlattenMethod("DeleteScalingRule", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}

140
vendor/github.com/denverdino/aliyungo/ess/schedule.go generated vendored Normal file
View File

@ -0,0 +1,140 @@
package ess
import "github.com/denverdino/aliyungo/common"
type RecurrenceType string
const (
Daily = RecurrenceType("Daily")
Weekly = RecurrenceType("Weekly")
Monthly = RecurrenceType("Monthly")
)
type CreateScheduledTaskArgs struct {
RegionId common.Region
ScheduledAction string
LaunchTime string
ScheduledTaskName string
Description string
LaunchExpirationTime int
RecurrenceType RecurrenceType
RecurrenceValue string
RecurrenceEndTime string
TaskEnabled bool
}
type CreateScheduledTaskResponse struct {
common.Response
ScheduledTaskId string
}
// CreateScheduledTask create schedule task
//
// You can read doc at https://help.aliyun.com/document_detail/25957.html?spm=5176.doc25950.6.638.FfQ0BR
func (client *Client) CreateScheduledTask(args *CreateScheduledTaskArgs) (resp *CreateScheduledTaskResponse, err error) {
response := CreateScheduledTaskResponse{}
err = client.Invoke("CreateScheduledTask", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type ModifyScheduledTaskArgs struct {
RegionId common.Region
ScheduledTaskId string
ScheduledAction string
LaunchTime string
ScheduledTaskName string
Description string
LaunchExpirationTime int
RecurrenceType RecurrenceType
RecurrenceValue string
RecurrenceEndTime string
TaskEnabled bool
}
type ModifyScheduledTaskResponse struct {
common.Response
}
// ModifyScheduledTask modify schedule task
//
// You can read doc at https://help.aliyun.com/document_detail/25958.html?spm=5176.doc25957.6.639.rgxQ1c
func (client *Client) ModifyScheduledTask(args *ModifyScheduledTaskArgs) (resp *ModifyScheduledTaskResponse, err error) {
response := ModifyScheduledTaskResponse{}
err = client.Invoke("ModifyScheduledTask", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}
type DescribeScheduledTasksArgs struct {
RegionId common.Region
ScheduledTaskId common.FlattenArray
ScheduledTaskName common.FlattenArray
ScheduledAction common.FlattenArray
common.Pagination
}
type DescribeScheduledTasksResponse struct {
common.Response
common.PaginationResult
ScheduledTasks struct {
ScheduledTask []ScheduledTaskItemType
}
}
type ScheduledTaskItemType struct {
ScheduledTaskId string
ScheduledTaskName string
Description string
ScheduledAction string
LaunchTime string
RecurrenceType string
RecurrenceValue string
RecurrenceEndTime string
LaunchExpirationTime int
TaskEnabled bool
}
// DescribeScheduledTasks describes scaling tasks
//
// You can read doc at https://help.aliyun.com/document_detail/25959.html?spm=5176.doc25958.6.640.cLccdR
func (client *Client) DescribeScheduledTasks(args *DescribeScheduledTasksArgs) (tasks []ScheduledTaskItemType, pagination *common.PaginationResult, err error) {
args.Validate()
response := DescribeScheduledTasksResponse{}
err = client.InvokeByFlattenMethod("DescribeScheduledTasks", args, &response)
if err == nil {
return response.ScheduledTasks.ScheduledTask, &response.PaginationResult, nil
}
return nil, nil, err
}
type DeleteScheduledTaskArgs struct {
RegionId common.Region
ScheduledTaskId string
}
type DeleteScheduledTaskResponse struct {
common.Response
}
// DeleteScheduledTask delete schedule task
//
// You can read doc at https://help.aliyun.com/document_detail/25960.html?spm=5176.doc25959.6.641.aGdNuW
func (client *Client) DeleteScheduledTask(args *DeleteScheduledTaskArgs) (resp *DeleteScheduledTaskResponse, err error) {
response := DeleteScheduledTaskResponse{}
err = client.Invoke("DeleteScheduledTask", args, &response)
if err != nil {
return nil, err
}
return &response, nil
}

View File

@ -7,9 +7,26 @@ import (
"net/url"
"reflect"
"strconv"
"strings"
"time"
)
// change instance=["a", "b"]
// to instance.1="a" instance.2="b"
func FlattenFn(fieldName string, field reflect.Value, values *url.Values) {
l := field.Len()
if l > 0 {
for i := 0; i < l; i++ {
str := field.Index(i).String()
values.Set(fieldName+"."+strconv.Itoa(i+1), str)
}
}
}
func Underline2Dot(name string) string {
return strings.Replace(name, "_", ".", -1)
}
//ConvertToQueryValues converts the struct to url.Values
func ConvertToQueryValues(ifc interface{}) url.Values {
values := url.Values{}
@ -22,6 +39,10 @@ func SetQueryValues(ifc interface{}, values *url.Values) {
setQueryValues(ifc, values, "")
}
func SetQueryValueByFlattenMethod(ifc interface{}, values *url.Values) {
setQueryValuesByFlattenMethod(ifc, values, "")
}
func setQueryValues(i interface{}, values *url.Values, prefix string) {
// add to support url.Values
mapValues, ok := i.(url.Values)
@ -150,3 +171,144 @@ func setQueryValues(i interface{}, values *url.Values, prefix string) {
}
}
}
func setQueryValuesByFlattenMethod(i interface{}, values *url.Values, prefix string) {
// add to support url.Values
mapValues, ok := i.(url.Values)
if ok {
for k, _ := range mapValues {
values.Set(k, mapValues.Get(k))
}
return
}
elem := reflect.ValueOf(i)
if elem.Kind() == reflect.Ptr {
elem = elem.Elem()
}
elemType := elem.Type()
for i := 0; i < elem.NumField(); i++ {
fieldName := elemType.Field(i).Name
anonymous := elemType.Field(i).Anonymous
field := elem.Field(i)
// TODO Use Tag for validation
// tag := typ.Field(i).Tag.Get("tagname")
kind := field.Kind()
if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() {
continue
}
if kind == reflect.Ptr {
field = field.Elem()
kind = field.Kind()
}
var value string
//switch field.Interface().(type) {
switch kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
i := field.Int()
if i != 0 {
value = strconv.FormatInt(i, 10)
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
i := field.Uint()
if i != 0 {
value = strconv.FormatUint(i, 10)
}
case reflect.Float32:
value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
case reflect.Float64:
value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
case reflect.Bool:
value = strconv.FormatBool(field.Bool())
case reflect.String:
value = field.String()
case reflect.Map:
ifc := field.Interface()
m := ifc.(map[string]string)
if m != nil {
j := 0
for k, v := range m {
j++
keyName := fmt.Sprintf("%s.%d.Key", fieldName, j)
values.Set(keyName, k)
valueName := fmt.Sprintf("%s.%d.Value", fieldName, j)
values.Set(valueName, v)
}
}
case reflect.Slice:
if field.Type().Name() == "FlattenArray" {
FlattenFn(fieldName, field, values)
} else {
switch field.Type().Elem().Kind() {
case reflect.Uint8:
value = string(field.Bytes())
case reflect.String:
l := field.Len()
if l > 0 {
strArray := make([]string, l)
for i := 0; i < l; i++ {
strArray[i] = field.Index(i).String()
}
bytes, err := json.Marshal(strArray)
if err == nil {
value = string(bytes)
} else {
log.Printf("Failed to convert JSON: %v", err)
}
}
default:
l := field.Len()
for j := 0; j < l; j++ {
prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
ifc := field.Index(j).Interface()
//log.Printf("%s : %v", prefixName, ifc)
if ifc != nil {
setQueryValuesByFlattenMethod(ifc, values, prefixName)
}
}
continue
}
}
default:
switch field.Interface().(type) {
case ISO6801Time:
t := field.Interface().(ISO6801Time)
value = t.String()
case time.Time:
t := field.Interface().(time.Time)
value = GetISO8601TimeStamp(t)
default:
ifc := field.Interface()
if ifc != nil {
if anonymous {
SetQueryValues(ifc, values)
} else {
prefixName := fieldName + "."
setQueryValuesByFlattenMethod(ifc, values, prefixName)
}
continue
}
}
}
if value != "" {
name := elemType.Field(i).Tag.Get("ArgName")
if name == "" {
name = fieldName
}
if prefix != "" {
name = prefix + name
}
// NOTE: here we will change name to underline style when the type is UnderlineString
if field.Type().Name() == "UnderlineString" {
name = Underline2Dot(name)
}
values.Set(name, value)
}
}
}

32
vendor/vendor.json vendored
View File

@ -1300,34 +1300,40 @@
"revisionTime": "2016-10-29T20:57:26Z"
},
{
"checksumSHA1": "SdiAYZOqWQ60ifRUHLwLiDMKMYA=",
"checksumSHA1": "4YIveqfMA1MH8oX8YMG7rDSl+ms=",
"path": "github.com/denverdino/aliyungo/common",
"revision": "c4c75afbf7ea86e66672c1b6ed981385b4ad5ec2",
"revisionTime": "2017-03-21T07:55:32Z"
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
"revisionTime": "2017-04-13T09:54:00Z"
},
{
"checksumSHA1": "UVYu5rvfoXgJnIpUyGcaovMvpms=",
"checksumSHA1": "WkWWoA5aRYkE2apOEQdAOfn+9cc=",
"path": "github.com/denverdino/aliyungo/ecs",
"revision": "c4c75afbf7ea86e66672c1b6ed981385b4ad5ec2",
"revisionTime": "2017-03-21T07:55:32Z"
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
"revisionTime": "2017-04-13T09:54:00Z"
},
{
"checksumSHA1": "BgIs8qwCMRM8xL6oLeo2Ki1QwBc=",
"path": "github.com/denverdino/aliyungo/ess",
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
"revisionTime": "2017-04-13T09:54:00Z"
},
{
"checksumSHA1": "riQMe2AR7qkLRkQ/MSr8gQp3zL4=",
"path": "github.com/denverdino/aliyungo/rds",
"revision": "c4c75afbf7ea86e66672c1b6ed981385b4ad5ec2",
"revisionTime": "2017-03-21T07:55:32Z"
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
"revisionTime": "2017-04-13T09:54:00Z"
},
{
"checksumSHA1": "2g6VZONB51rul5YuSBvngH6u4A0=",
"path": "github.com/denverdino/aliyungo/slb",
"revision": "c4c75afbf7ea86e66672c1b6ed981385b4ad5ec2",
"revisionTime": "2017-03-21T07:55:32Z"
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
"revisionTime": "2017-04-13T09:54:00Z"
},
{
"checksumSHA1": "Lp0KtT7ycgq31ox3Uzhpxyw0U+Y=",
"checksumSHA1": "piZlmhWPLGxYkXLysTrjcXllO4c=",
"path": "github.com/denverdino/aliyungo/util",
"revision": "c4c75afbf7ea86e66672c1b6ed981385b4ad5ec2",
"revisionTime": "2017-03-21T07:55:32Z"
"revision": "afcc6903e3f10217da17e315558b3f829718ee04",
"revisionTime": "2017-04-13T09:54:00Z"
},
{
"checksumSHA1": "yDQQpeUxwqB3C+4opweg6znWJQk=",

View File

@ -6,7 +6,7 @@ description: |-
Provides an RDS instance resource.
---
# alicloud_db_instance
# alicloud\_db\_instance
Provides an RDS instance resource. A DB instance is an isolated database
environment in the cloud. A DB instance can contain multiple user-created
@ -14,16 +14,14 @@ databases.
## Example Usage
```hcl
```
resource "alicloud_db_instance" "default" {
commodity_code = "rds"
engine = "MySQL"
engine_version = "5.6"
db_instance_class = "rds.mysql.t1.small"
db_instance_storage = "10"
db_instance_net_type = "Intranet"
commodity_code = "rds"
engine = "MySQL"
engine_version = "5.6"
db_instance_class = "rds.mysql.t1.small"
db_instance_storage = "10"
db_instance_net_type = "Intranet"
}
```
@ -32,13 +30,13 @@ resource "alicloud_db_instance" "default" {
The following arguments are supported:
* `engine` - (Required) Database type. Value options: MySQL, SQLServer, PostgreSQL, and PPAS.
* `engine_version` - (Required) Database version. Value options:
* `engine_version` - (Required) Database version. Value options:
- 5.5/5.6/5.7 for MySQL
- 2008r2/2012 for SQLServer
- 9.4 for PostgreSQL
- 9.3 for PPAS
* `db_instance_class` - (Required) Instance type. For details, see [Instance type table](https://intl.aliyun.com/help/doc-detail/26312.htm?spm=a3c0i.o26228en.a3.2.bRUHF3).
* `db_instance_storage` - (Required) User-defined storage space. Value range:
* `db_instance_storage` - (Required) User-defined storage space. Value range:
- [5, 2000] for MySQL/PostgreSQL/PPAS HA dual node edition;
- [20,1000] for MySQL 5.7 basic single node edition;
- [10, 2000] for SQL Server 2008R2;
@ -65,7 +63,7 @@ The following arguments are supported:
The database mapping supports the following:
* `db_name` - (Required) Name of the database requiring a uniqueness check. It may consist of lower case letters, numbers and underlines, and must start with a letter and have no more than 64 characters.
* `db_name` - (Required) Name of the database requiring a uniqueness check. It may consist of lower case letters, numbers and underlines, and must start with a letter and have no more than 64 characters.
* `character_set_name` - (Required) Character set. The value range is limited to the following:
- MySQL type:
+ utf8
@ -78,7 +76,7 @@ The database mapping supports the following:
+ SQL_Latin1_General_CP1_CI_AS
+ SQL_Latin1_General_CP1_CS_AS
+ Chinese_PRC_BIN
* `db_description` - (Optional) Database description, which cannot exceed 256 characters. NOTE: It cannot begin with https://.
* `db_description` - (Optional) Database description, which cannot exceed 256 characters. NOTE: It cannot begin with https://.
~> **NOTE:** We neither support modify any of database attribute, nor insert/remove item at the same time.
@ -105,3 +103,4 @@ The following attributes are exported:
* `backup_retention_period` - Retention days of the backup.
* `security_ips` - Security ips of instance whitelist.
* `connections` - Views all the connection information of a specified instance.

View File

@ -1,12 +1,12 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_disk"
sidebar_current: "docs-alicloud-resource-disk."
sidebar_current: "docs-alicloud-resource-disk"
description: |-
Provides a ECS Disk resource.
---
# alicloud_disk
# alicloud\_disk
Provides a ECS disk resource.
@ -14,8 +14,10 @@ Provides a ECS disk resource.
## Example Usage
```hcl
```
# Create a new ECS disk.
resource "alicloud_disk" "ecs_disk" {
# cn-beijing
availability_zone = "cn-beijing-b"
name = "New-disk"
description = "Hello ecs disk."
@ -32,7 +34,7 @@ resource "alicloud_disk" "ecs_disk" {
The following arguments are supported:
* `availability_zone` - (Required, Forces new resource) The Zone to create the disk in.
* `name` - (Optional) Name of the ECS disk. This 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://. Default value is null.
* `name` - (Optional) Name of the ECS disk. This 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://. Default value is null.
* `description` - (Optional) Description of the disk. This description can have a string of 2 to 256 characters, It cannot begin with http:// or https://. Default value is null.
* `category` - (Optional, Forces new resource) Category of the disk. Valid values are `cloud`, `cloud_efficiency` and `cloud_ssd`. Default is `cloud`.
* `size` - (Required) The size of the disk in GiBs, and its value depends on `Category`. `cloud` disk value range: 5GB ~ 2000GB and other category disk value range: 20 ~ 32768.
@ -51,4 +53,4 @@ The following attributes are exported:
* `category` - The disk category.
* `size` - The disk size.
* `snapshot_id` - The disk snapshot ID.
* `tags` - The disk tags.
* `tags` - The disk tags.

View File

@ -6,7 +6,7 @@ description: |-
Provides a ECS Disk Attachment resource.
---
# alicloud_disk_attachment
# alicloud\_disk\_attachment
Provides an Alicloud ECS Disk Attachment as a resource, to attach and detach disks from ECS Instances.
@ -14,7 +14,9 @@ Provides an Alicloud ECS Disk Attachment as a resource, to attach and detach dis
Basic usage
```hcl
```
# Create a new ECS disk-attachment and use it attach one disk to a new instance.
resource "alicloud_security_group" "ecs_sg" {
name = "terraform-test-group"
description = "New security group"
@ -63,4 +65,4 @@ The following attributes are exported:
* `instance_id` - ID of the Instance.
* `disk_id` - ID of the Disk.
* `device_name` - The device name exposed to the instance.
* `device_name` - The device name exposed to the instance.

View File

@ -1,18 +1,18 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_eip"
sidebar_current: "docs-alicloud-resource-eip."
sidebar_current: "docs-alicloud-resource-eip"
description: |-
Provides a ECS EIP resource.
---
# alicloud_eip
# alicloud\_eip
Provides a ECS EIP resource.
## Example Usage
```hcl
```
# Create a new EIP.
resource "alicloud_eip" "example" {
bandwidth = "10"

View File

@ -6,7 +6,7 @@ description: |-
Provides a ECS EIP Association resource.
---
# alicloud_eip_association
# alicloud\_eip\_association
Provides an Alicloud EIP Association resource, to associate and disassociate Elastic IPs from ECS Instances.
@ -16,7 +16,9 @@ Provides an Alicloud EIP Association resource, to associate and disassociate Ela
## Example Usage
```hcl
```
# Create a new EIP association and use it to associate a EIP form a instance.
resource "alicloud_vpc" "vpc" {
cidr_block = "10.1.0.0/21"
}
@ -71,4 +73,4 @@ The following arguments are supported:
The following attributes are exported:
* `allocation_id` - As above.
* `instance_id` - As above.
* `instance_id` - As above.

View File

@ -0,0 +1,84 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_ess_scaling_configuration"
sidebar_current: "docs-alicloud-resource-ess-scaling-configuration"
description: |-
Provides a ESS scaling configuration resource.
---
# alicloud\_ess\_scaling\_configuration
Provides a ESS scaling configuration resource.
## Example Usage
```
resource "alicloud_security_group" "classic" {
# Other parameters...
}
resource "alicloud_ess_scaling_group" "scaling" {
min_size = 1
max_size = 2
removal_policies = ["OldestInstance", "NewestInstance"]
}
resource "alicloud_ess_scaling_configuration" "config" {
scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}"
image_id = "ubuntu_140405_64_40G_cloudinit_20161115.vhd"
instance_type = "ecs.s2.large"
security_group_id = "${alicloud_security_group.classic.id}"
}
```
## Argument Reference
The following arguments are supported:
* `scaling_group_id` - (Required) ID of the scaling group of a scaling configuration.
* `image_id` - (Required) ID of an image file, indicating the image resource selected when an instance is enabled.
* `instance_type` - (Required) Resource type of an ECS instance.
* `io_optimized` - (Required) Valid values are `none`, `optimized`, If `optimized`, the launched ECS instance will be I/O optimized.
* `security_group_id` - (Required) ID of the security group to which a newly created instance belongs.
* `scaling_configuration_name` - (Optional) Name shown for the scheduled task. If this parameter value is not specified, the default value is ScalingConfigurationId.
* `internet_charge_type` - (Optional) Network billing type, Values: PayByBandwidth or PayByTraffic. If this parameter value is not specified, the default value is PayByBandwidth.
* `internet_max_bandwidth_in` - (Optional) Maximum incoming bandwidth from the public network, measured in Mbps (Mega bit per second). The value range is [1,200].
* `internet_max_bandwidth_out` - (Optional) Maximum outgoing bandwidth from the public network, measured in Mbps (Mega bit per second). The value range for PayByBandwidth is [1,100].
* `system_disk_category` - (Optional) Category of the system disk. The parameter value options are cloud and ephemeral.
* `data_disk` - (Optional) DataDisk mappings to attach to ecs instance. See [Block datadisk](#block-datadisk) below for details.
* `instance_ids` - (Optional) ID of the ECS instance to be attached to the scaling group after it is enabled. You can input up to 20 IDs.
## Block datadisk
The datadisk mapping supports the following:
* `size` - (Optional) Size of data disk, in GB. The value ranges from 5 to 2,000 for a cloud disk and from 5 to 1,024 for an ephemeral disk. A maximum of four values can be entered.
* `category` - (Optional) Category of data disk. The parameter value options are cloud and ephemeral.
* `snapshot_id` - (Optional) Snapshot used for creating the data disk. If this parameter is specified, the size parameter is neglected, and the size of the created disk is the size of the snapshot.
* `device` - (Optional) Attaching point of the data disk. If this parameter is empty, the ECS automatically assigns the attaching point when an ECS is created. The parameter value ranges from /dev/xvdb to /dev/xvdz. Restrictions on attaching ECS instances:
- The attached ECS instance and the scaling group must be in the same region.
- The attached ECS instance and the instance with active scaling configurations must be of the same type.
- The attached ECS instance must in the running state.
- The attached ECS instance has not been attached to other scaling groups.
- The attached ECS instance supports Subscription and Pay-As-You-Go payment methods.
- If the VswitchID is specified for a scaling group, you cannot attach Classic ECS instances or ECS instances on other VPCs to the scaling group.
- If the VswitchID is not specified for the scaling group, ECS instances of the VPC type cannot be attached to the scaling group
* `active` - (Optional) If active current scaling configuration in the scaling group.
* `enable` - (Optional) Enables the specified scaling group.
- After the scaling group is successfully enabled (the group is active), the ECS instances specified by the interface are attached to the group.
- If the current number of ECS instances in the scaling group is still smaller than MinSize after the ECS instances specified by the interface are attached, the Auto Scaling service automatically creates ECS instances in Pay-As-You-Go mode to make odds even. For example, a scaling group is created with MinSize = 5. Two existing ECS instances are specified by the InstanceId.N parameter when the scaling group is enabled. Three additional ECS instances are automatically created after the two ECS instances are attached by the Auto Scaling service to the scaling group.
## Attributes Reference
The following attributes are exported:
* `id` - The scaling configuration ID.
* `active` - Wether the current scaling configuration is actived.
* `image_id` - The ecs instance Image id.
* `instance_type` - The ecs instance type.
* `io_optimized` - The ecs instance whether I/O optimized.
* `security_group_id` - ID of the security group to which a newly created instance belongs.
* `scaling_configuration_name` - Name of scaling configuration.
* `internet_charge_type` - Internet charge type of ecs instance.

View File

@ -0,0 +1,57 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_ess_scaling_group"
sidebar_current: "docs-alicloud-resource-ess-scaling-group"
description: |-
Provides a ESS scaling group resource.
---
# alicloud\_ess\_scaling\_group
Provides a ESS scaling group resource.
## Example Usage
```
resource "alicloud_ess_scaling_group" "scaling" {
min_size = 1
max_size = 2
removal_policies = ["OldestInstance", "NewestInstance"]
}
```
## Argument Reference
The following arguments are supported:
* `min_size` - (Required) Minimum number of ECS instances in the scaling group. Value range: [0, 100].
* `max_size` - (Required) Maximum number of ECS instances in the scaling group. Value range: [0, 100].
* `scaling_group_name` - (Optional) Name shown for the scaling group, which must contain 2-40 characters (English or Chinese). If this parameter is not specified, the default value is ScalingGroupId.
* `default_cooldown` - (Optional) Default cool-down time (in seconds) of the scaling group. Value range: [0, 86400]. The default value is 300s.
* `vswitch_id` - (Optional) The virtual switch ID which the ecs instance to be create in.
* `removal_policies` - (Optional) RemovalPolicy is used to select the ECS instances you want to remove from the scaling group when multiple candidates for removal exist. Optional values:
- OldestInstance: removes the first ECS instance attached to the scaling group.
- NewestInstance: removes the first ECS instance attached to the scaling group.
- OldestScalingConfiguration: removes the ECS instance with the oldest scaling configuration.
- Default values: OldestScalingConfiguration and OldestInstance. You can enter up to two removal policies.
* `db_instance_ids` - (Optional) If an RDS instance is specified in the scaling group, the scaling group automatically attaches the Intranet IP addresses of its ECS instances to the RDS access whitelist.
- The specified RDS instance must be in running status.
- The specified RDS instances whitelist must have room for more IP addresses.
* `loadbalancer_ids` - (Optional) If a Server Load Balancer instance is specified in the scaling group, the scaling group automatically attaches its ECS instances to the Server Load Balancer instance.
- The Server Load Balancer instance must be enabled.
- Health check must be enabled for all listener ports configured for the Server Load Balancer instance; otherwise, creation fails.
- The Server Load Balancer instance attached with VPC-type ECS instances cannot be attached to the scaling group.
- The default weight of an ECS instance attached to the Server Load Balancer instance is 50.
## Attributes Reference
The following attributes are exported:
* `id` - The scaling group ID.
* `min_size` - The minimum number of ECS instances.
* `max_size` - The maximum number of ECS instances.
* `scaling_group_name` - The name of the scaling group.
* `default_cooldown` - The default cool-down of the scaling group.
* `removal_policies` - The removal policy used to select the ECS instance to remove from the scaling group.
* `db_instance_ids` - The db instance id which the ECS instance attached to.
* `loadbalancer_ids` - The slb instance id which the ECS instance attached to.

View File

@ -0,0 +1,59 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_ess_scaling_rule"
sidebar_current: "docs-alicloud-resource-ess-scaling-rule"
description: |-
Provides a ESS scaling rule resource.
---
# alicloud\_ess\_scaling\_rule
Provides a ESS scaling rule resource.
## Example Usage
```
resource "alicloud_ess_scaling_group" "scaling" {
# Other parameters...
}
resource "alicloud_ess_scaling_configuration" "config" {
# Other parameters...
}
resource "alicloud_ess_scaling_rule" "rule" {
scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}"
adjustment_type = "TotalCapacity"
adjustment_value = 2
cooldown = 60
}
```
## Argument Reference
The following arguments are supported:
* `scaling_group_id` - (Required) ID of the scaling group of a scaling rule.
* `adjustment_type` - (Required) Adjustment mode of a scaling rule. Optional values:
- QuantityChangeInCapacity: It is used to increase or decrease a specified number of ECS instances.
- PercentChangeInCapacity: It is used to increase or decrease a specified proportion of ECS instances.
- TotalCapacity: It is used to adjust the quantity of ECS instances in the current scaling group to a specified value.
* `adjustment_value` - (Required) Adjusted value of a scaling rule. Value range:
- QuantityChangeInCapacity(0, 100] U (-100, 0]
- PercentChangeInCapacity[0, 10000] U [-10000, 0]
- TotalCapacity[0, 100]
* `scaling_rule_name` - (Optional) Name shown for the scaling rule, which is a string containing 2 to 40 English or Chinese characters.
* `cooldown` - (Optional) Cool-down time of a scaling rule. Value range: [0, 86,400], in seconds. The default value is empty.
## Attributes Reference
The following attributes are exported:
* `id` - The scaling rule ID.
* `scaling_group_id` - The id of scaling group.
* `ari` - Unique identifier of a scaling rule.
* `adjustment_type` - Adjustment mode of a scaling rule.
* `adjustment_value` - Adjustment value of a scaling rule.
* `scaling_rule_name` - Name of a scaling rule.
* `cooldown` - Cool-down time of a scaling rule.

View File

@ -0,0 +1,65 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_ess_schedule"
sidebar_current: "docs-alicloud-resource-ess-schedule"
description: |-
Provides a ESS schedule resource.
---
# alicloud\_ess\_schedule
Provides a ESS schedule resource.
## Example Usage
```
resource "alicloud_ess_scaling_group" "scaling" {
# Other parameters...
}
resource "alicloud_ess_scaling_configuration" "config" {
# Other parameters...
}
resource "alicloud_ess_scaling_rule" "rule" {
# Other parameters...
}
resource "alicloud_ess_schedule" "schedule" {
scheduled_action = "${alicloud_ess_scaling_rule.rule.ari}"
launch_time = "2017-04-29T07:30Z"
scheduled_task_name = "sg-schedule"
}
```
## Argument Reference
The following arguments are supported:
* `scheduled_action` - (Required) Operations performed when the scheduled task is triggered. Fill in the unique identifier of the scaling rule.
* `launch_time` - (Required) Operations performed when the scheduled task is triggered. Fill in the unique identifier of the scaling rule.
* `scheduled_task_name` - (Optional) Display name of the scheduled task, which must be 2-40 characters (English or Chinese) long.
* `description` - (Optional) Description of the scheduled task, which is 2-200 characters (English or Chinese) long.
* `launch_expiration_time` - (Optional) Time period within which the failed scheduled task is retried. The default value is 600s. Value range: [0, 21600]
* `recurrence_type` - (Optional) Type of the scheduled task to be repeated. RecurrenceType, RecurrenceValue and RecurrenceEndTime must be specified. Optional values:
- Daily: Recurrence interval by day for a scheduled task.
- Weekly: Recurrence interval by week for a scheduled task.
- Monthly: Recurrence interval by month for a scheduled task.
* `recurrence_value` - (Optional) Value of the scheduled task to be repeated. RecurrenceType, RecurrenceValue and RecurrenceEndTime must be specified.
- Daily: Only one value in the range [1,31] can be filled.
- Weekly: Multiple values can be filled. The values of Sunday to Saturday are 0 to 6 in sequence. Multiple values shall be separated by a comma “,”.
- Monthly: In the format of A-B. The value range of A and B is 1 to 31, and the B value must be greater than the A value.
* `recurrence_end_time` - (Optional) End time of the scheduled task to be repeated. The date format follows the ISO8601 standard and uses UTC time. It is in the format of YYYY-MM-DDThh:mmZ. A time point 90 days after creation or modification cannot be entered. RecurrenceType, RecurrenceValue and RecurrenceEndTime must be specified.
* `task_enabled` - (Optional) Whether to enable the scheduled task. The default value is true.
## Attributes Reference
The following attributes are exported:
* `id` - The schedule task ID.
* `scheduled_action` - The action of schedule task.
* `launch_time` - The time of schedule task be triggered.
* `scheduled_task_name` - The name of schedule task.
* `description` - The description of schedule task.
* `task_enabled` - Wether the task is enabled.

View File

@ -0,0 +1,68 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_forward_entry"
sidebar_current: "docs-alicloud-resource-vpc"
description: |-
Provides a Alicloud forward resource.
---
# alicloud\_forward
Provides a forward resource.
## Example Usage
Basic Usage
```
resource "alicloud_vpc" "foo" {
...
}
resource "alicloud_vswitch" "foo" {
...
}
resource "alicloud_nat_gateway" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [
{
ip_count = 2
bandwidth = 5
zone = ""
},
{
ip_count = 1
bandwidth = 6
zone = "cn-beijing-b"
}
]
depends_on = [
"alicloud_vswitch.foo",
]
}
resource "alicloud_forward_entry" "foo" {
forward_table_id = "${alicloud_nat_gateway.foo.forward_table_ids}"
external_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
external_port = "80"
ip_protocol = "tcp"
internal_ip = "172.16.0.3"
internal_port = "8080"
}
```
## Argument Reference
The following arguments are supported:
* `forward_table_id` - (Required, Forces new resource) The value can get from `alicloud_nat_gateway` Attributes "forward_table_ids".
* `external_ip` - (Required, Forces new resource) The external ip address, the ip must along bandwidth package public ip which `alicloud_nat_gateway` argument `bandwidth_packages`.
* `external_port` - (Required) The external port, valid value is 1~65535|any.
* `ip_protocol` - (Required) The ip protocal, valid value is tcp|udp|any.
* `internal_ip` - (Required) The internal ip, must a private ip.
* `internal_port` - (Required) The internal port, valid value is 1~65535|any.

View File

@ -12,7 +12,7 @@ Provides a ECS instance resource.
## Example Usage
```hcl
```
# Create a new ECS instance for classic
resource "alicloud_security_group" "classic" {
name = "tf_test_foo"
@ -24,7 +24,7 @@ resource "alicloud_instance" "classic" {
availability_zone = "cn-beijing-b"
security_groups = ["${alicloud_security_group.classic.*.id}"]
allocate_public_ip = "true"
allocate_public_ip = true
# series II
instance_type = "ecs.n1.medium"
@ -36,11 +36,11 @@ resource "alicloud_instance" "classic" {
# Create a new ECS instance for VPC
resource "alicloud_vpc" "default" {
# ...
# Other parameters...
}
resource "alicloud_vswitch" "default" {
# ...
# Other parameters...
}
resource "alicloud_slb" "vpc" {
@ -59,18 +59,17 @@ The following arguments are supported:
* `io_optimized` - (Required) Valid values are `none`, `optimized`, If `optimized`, the launched ECS instance will be I/O optimized.
* `security_groups` - (Optional) A list of security group ids to associate with.
* `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`.
* `allocate_public_ip` - (Optional) Associate a public ip address with an instance in a VPC or Classic. Boolean value, Default is false.
* `system_disk_category` - (Optional) Valid values are `cloud`, `cloud_efficiency`, `cloud_ssd`, For I/O optimized instance type, `cloud_ssd` and `cloud_efficiency` disks are supported. For non I/O Optimized instance type, `cloud` disk are supported.
* `system_disk_category` - (Optional) Valid values are `cloud`, `cloud_efficiency`, `cloud_ssd`, For I/O optimized instance type, `cloud_ssd` and `cloud_efficiency` disks are supported. For non I/O Optimized instance type, `cloud` disk are supported.
* `system_disk_size` - (Optional) Size of the system disk, value range: 40GB ~ 500GB. Default is 40GB.
* `description` - (Optional) Description of the instance, This description can have a string of 2 to 256 characters, It cannot begin with http:// or https://. Default value is null.
* `internet_charge_type` - (Optional) Internet charge type of the instance, Valid values are `PayByBandwidth`, `PayByTraffic`. Default is `PayByBandwidth`.
* `internet_max_bandwidth_in` - (Optional) Maximum incoming bandwidth from the public network, measured in Mbps (Mega bit per second). Value range: [1, 200]. If this value is not specified, then automatically sets it to 200 Mbps.
* `internet_max_bandwidth_out` - (Optional) Maximum outgoing bandwidth to the public network, measured in Mbps (Mega bit per second). Value range:
`internet_charge_type` is `PayByBandwidth`: this value range [0, 100], If this value is not specified, then automatically sets it to 0 Mbps; If `internet_charge_type` is `PayByTraffic`: this value range [1, 100]. this value must be set value, such as 5.
* `host_name` - (Optional) Host name of the ECS, which is a string of at least two characters. "hostname” cannot start or end with ".” or "-". In addition, two or more consecutive ".” or "-" symbols are not allowed. On Windows, the host name can contain a maximum of 15 characters, which can be a combination of uppercase/lowercase letters, numerals, and "-". The host name cannot contain dots (".”) or contain only numeric characters.
On other OSs such as Linux, the host name can contain a maximum of 30 characters, which can be segments separated by dots (".”), where each segment can contain uppercase/lowercase letters, numerals, or "\_".
* `internet_max_bandwidth_out` - (Optional) Maximum outgoing bandwidth to the public network, measured in Mbps (Mega bit per second). Value range: [0, 100], If this value is not specified, then automatically sets it to 0 Mbps.
* `host_name` - (Optional) Host name of the ECS, which is a string of at least two characters. “hostname” cannot start or end with “.” or “-“. In addition, two or more consecutive “.” or “-“ symbols are not allowed. On Windows, the host name can contain a maximum of 15 characters, which can be a combination of uppercase/lowercase letters, numerals, and “-“. The host name cannot contain dots (“.”) or contain only numeric characters.
On other OSs such as Linux, the host name can contain a maximum of 30 characters, which can be segments separated by dots (“.”), where each segment can contain uppercase/lowercase letters, numerals, or “_“.
* `password` - (Optional) Password to an instance is a string of 8 to 30 characters. It must contain uppercase/lowercase letters and numerals, but cannot contain special symbols.
* `vswitch_id` - (Optional) The virtual switch ID to launch in VPC. If you want to create instances in VPC network, this parameter must be set.
* `instance_charge_type` - (Optional) Valid values are `PrePaid`, `PostPaid`, The default is `PostPaid`.
@ -94,4 +93,4 @@ The following attributes are exported:
* `private_ip` - The instance private ip.
* `public_ip` - The instance public ip.
* `vswitch_id` - If the instance created in VPC, then this value is virtual switch ID.
* `tags` - The instance tags, use jsonencode(item) to display the value.
* `tags` - The instance tags, use jsonencode(item) to display the value.

View File

@ -6,15 +6,18 @@ description: |-
Provides a resource to create a VPC NAT Gateway.
---
# alicloud_nat_gateway
# alicloud\_nat\_gateway
Provides a resource to create a VPC NAT Gateway.
~> **NOTE:** alicloud_nat_gateway must depends on alicloud_vswitch.
## Example Usage
Basic usage
```hcl
```
resource "alicloud_vpc" "vpc" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
@ -31,12 +34,11 @@ resource "alicloud_nat_gateway" "nat_gateway" {
spec = "Small"
name = "test_foo"
bandwidth_packages = [
{
ip_count = 1
bandwidth = 5
zone = "cn-beijing-b"
},
bandwidth_packages = [{
ip_count = 1
bandwidth = 5
zone = "cn-beijing-b"
},
{
ip_count = 2
bandwidth = 10
@ -56,7 +58,7 @@ The following arguments are supported:
* `vpc_id` - (Required, Forces New Resorce) The VPC ID.
* `spec` - (Required, Forces New Resorce) The specification of the nat gateway. Valid values are `Small`, `Middle` and `Large`. Details refer to [Nat Gateway Specification](https://help.aliyun.com/document_detail/42757.html?spm=5176.doc32322.6.559.kFNBzv)
* `name` - (Optional) Name of the nat gateway. The value 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://. Defaults to null.
* `name` - (Optional) Name of the nat gateway. The value 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://. Defaults to null.
* `description` - (Optional) Description of the nat gateway, This description can have a string of 2 to 256 characters, It cannot begin with http:// or https://. Defaults to null.
* `bandwidth_packages` - (Required) A list of bandwidth packages for the nat gatway.
@ -67,6 +69,7 @@ The bandwidth package mapping supports the following:
* `ip_count` - (Required) The IP number of the current bandwidth package. Its value range from 1 to 50.
* `bandwidth` - (Required) The bandwidth value of the current bandwidth package. Its value range from 5 to 5000.
* `zone` - (Optional) The AZ for the current bandwidth. If this value is not specified, Terraform will set a random AZ.
* `public_ip_addresses` - (Computer) The public ip for bandwidth package. the public ip count equal `ip_count`, multi ip would complex with ",", such as "10.0.0.1,10.0.0.2".
## Attributes Reference
@ -78,3 +81,5 @@ The following attributes are exported:
* `spec` - The specification of the nat gateway.
* `vpc_id` - The VPC ID for the nat gateway.
* `bandwidth_package_ids` - A list ID of the bandwidth packages, and split them with commas
* `snat_table_ids` - The nat gateway will auto create a snap and forward item, the `snat_table_ids` is the created one.
* `forward_table_ids` - The nat gateway will auto create a snap and forward item, the `forward_table_ids` is the created one.

View File

@ -1,12 +1,12 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_security_group"
sidebar_current: "docs-alicloud-resource-security-group."
sidebar_current: "docs-alicloud-resource-security-group"
description: |-
Provides a Alicloud Security Group resource.
---
# alicloud_security_group
# alicloud\_security\_group
Provides a security group resource.
@ -16,16 +16,15 @@ Provides a security group resource.
Basic Usage
```hcl
```
resource "alicloud_security_group" "group" {
name = "terraform-test-group"
description = "New security group"
}
```
Basic usage for vpc
```hcl
```
resource "alicloud_security_group" "group" {
name = "new-group"
vpc_id = "${alicloud_vpc.vpc.id}"
@ -51,4 +50,4 @@ The following attributes are exported:
* `id` - The ID of the security group
* `vpc_id` - The VPC ID.
* `name` - The name of the security group
* `description` - The description of the security group
* `description` - The description of the security group

View File

@ -6,7 +6,7 @@ description: |-
Provides a Alicloud Security Group Rule resource.
---
# alicloud_security_group_rule
# alicloud\_security\_group\_rule
Provides a security group rule resource.
Represents a single `ingress` or `egress` group rule, which can be added to external Security Groups.
@ -18,7 +18,7 @@ Represents a single `ingress` or `egress` group rule, which can be added to exte
Basic Usage
```hcl
```
resource "alicloud_security_group" "default" {
name = "default"
}
@ -58,4 +58,4 @@ The following attributes are exported:
* `type` - The type of rule, `ingress` or `egress`
* `name` - The name of the security group
* `port_range` - The range of port numbers
* `ip_protocol` - The protocol of the security group rule
* `ip_protocol` - The protocol of the security group rule

View File

@ -1,18 +1,18 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_slb"
sidebar_current: "docs-alicloud-resource-slb."
sidebar_current: "docs-alicloud-resource-slb"
description: |-
Provides an Application Load Banlancer resource.
---
# alicloud_slb
# alicloud\_slb
Provides an Application Load Balancer resource.
## Example Usage
```hcl
```
# Create a new load balancer for classic
resource "alicloud_slb" "classic" {
name = "test-slb-tf"
@ -44,11 +44,11 @@ resource "alicloud_slb" "classic" {
# Create a new load balancer for VPC
resource "alicloud_vpc" "default" {
# ...
# Other parameters...
}
resource "alicloud_vswitch" "default" {
# ...
# Other parameters...
}
resource "alicloud_slb" "vpc" {
@ -62,7 +62,7 @@ resource "alicloud_slb" "vpc" {
The following arguments are supported:
* `name` - (Optional) The name of the SLB. This name must be unique within your AliCloud account, can have a maximum of 80 characters,
must contain only alphanumeric characters or hyphens, such as "-","/",".","\_", and must not begin or end with a hyphen. If not specified,
must contain only alphanumeric characters or hyphens, such as "-","/",".","_", and must not begin or end with a hyphen. If not specified,
Terraform will autogenerate a name beginning with `tf-lb`.
* `internet` - (Optional, Forces New Resource) If true, the SLB addressType will be internet, false will be intranet, Default is false. If load balancer launched in VPC, this value must be "false".
* `internet_charge_type` - (Optional, Forces New Resource) Valid
@ -74,12 +74,59 @@ Terraform will autogenerate a name beginning with `tf-lb`.
## Block listener
load balance support 4 protocal to listen on, they are `http`,`https`,`tcp`,`udp`, the every listener support which portocal following:
listener parameter | support protocol | value range |
------------- | ------------- | ------------- |
instance_port | http & https & tcp & udp | 1-65535 |
lb_port | http & https & tcp & udp | 1-65535 |
lb_protocol | http & https & tcp & udp |
bandwidth | http & https & tcp & udp | -1 / 1-1000 |
scheduler | http & https & tcp & udp | wrr or wlc |
sticky_session | http & https | on or off |
sticky_session_type | http & https | insert or server |
cookie_timeout | http & https | 1-86400 |
cookie | http & https | |
persistence_timeout | tcp & udp | 0-3600 |
health_check | http & https | on or off |
health_check_type | tcp | tcp or http |
health_check_domain | http & https & tcp |
health_check_uri | http & https & tcp | |
health_check_connect_port | http & https & tcp & udp | 1-65535 or -520 |
healthy_threshold | http & https & tcp & udp | 1-10 |
unhealthy_threshold | http & https & tcp & udp | 1-10 |
health_check_timeout | http & https & tcp & udp | 1-50 |
health_check_interval | http & https & tcp & udp | 1-5 |
health_check_http_code | http & https & tcp | http_2xx,http_3xx,http_4xx,http_5xx |
ssl_certificate_id | https | |
The listener mapping supports the following:
* `instance_port` - (Required) The port on which the backend servers are listening. Valid value is between 1 to 65535.
* `lb_port` - (Required) The port on which the load balancer is listening. Valid value is between 1 to 65535.
* `lb_protocol` - (Required) The protocol to listen on. Valid values are `http` and and `tcp` and `udp`.
* `bandwidth` - (Required) The bandwidth on which the load balancer is listening. Valid values is -1 or between 1 and 1000. If -1, the bindwidth will havent upper limit.
* `scheduler` - (Optinal) Scheduling algorithm, Valid Value is `wrr` / `wlc`, Default is "wrr".
* `sticky_session` - (Optinal) Whether to enable session persistence, Value: `on` / `off`.
* `sticky_session_type` - (Optinal) Mode for handling the cookie. If "sticky_session" is on, the parameter is mandatory, and if "sticky_session" is off, the parameter will be ignored. Value`insert` / `server`. If it is set to insert, it means it is inserted from Server Load Balancer; and if it is set to server, it means the Server Load Balancer learns from the backend server.
* `cookie_timeout` - (Optinal) The parameter is mandatory when "sticky_session" is on and "sticky_session_type" is insert. Otherwise, it will be ignored. Value 1-86400in seconds
* `cookie` - (Optinal) The cookie configured on the server
It is mandatory only when "sticky_session" is on and "sticky_session_type" is server; otherwise, the parameter will be ignored. ValueString in line with RFC 2965, with length being 1- 200. It only contains characters such as ASCII codes, English letters and digits instead of the comma, semicolon or spacing, and it cannot start with $.
* `persistence_timeout` - (Optinal) Timeout of connection persistence. Value 0-3600in seconds .Default0 The value 0 indicates to close it.
* `health_check` - (Optinal) Whether to enable health check. Value`on` / `off`
* `health_check_type` - (Optinal) Type of health check. Value`tcp` | `http` , Default`tcp` . TCP supports TCP and HTTP health check mode, you can select the particular mode depending on your application.
* `health_check_domain` - (Optinal) Domain name used for health check. When TCP listener need to use HTTP health check, this parameter will be configured; and when TCP health check is used, the parameter will be ignored. Value `$_ip | custom string`. Rules of the custom string: its length is limited to 1-80 and only characters such as letters, digits, - and . are allowed. When the parameter is set to $_ip by the user, Server Load Balancer uses the private network IP address of each backend server as Domain used for health check.
* `health_check_uri` - (Optinal) URI used for health check. When TCP listener need to use HTTP health check, this parameter will be configured; and when TCP health check is used, the parameter will be ignored.
ValueIts length is limited to 1-80 and it must start with /. Only characters such as letters, digits, -, /, ., %, ?, # and & are allowed.
* `health_check_connect_port` - (Optinal) Port used for health check. Value `1-65535`, DefaultNone. When the parameter is not set, it means the backend server port is used (BackendServerPort).
* `healthy_threshold` - (Optinal) Threshold determining the result of the health check is success. Value`1-10`, Default3.
* `unhealthy_threshold` - (Optinal) Threshold determining the result of the health check is fail. Value`1-10`, Default3.
* `health_check_timeout` - (Optinal) Maximum timeout of each health check response. When "health_check" is on, the parameter is mandatory; and when "mandatory" is off, the parameter will be ignored. Value`1-50`in seconds. Note: If health_check_timeout < health_check_interval, health_check_timeout is invalid, and the timeout is health_check_interval.
* `health_check_interval` - (Optinal) Time interval of health checks.
When "health_check" is on, the parameter is mandatory; and when "health_check" is off, the parameter will be ignored. Value`1-5` (in seconds
* `health_check_http_code` - (Optinal) Regular health check HTTP status code. Multiple codes are segmented by “,”. When "health_check" is on, the parameter is mandatory; and when "health_check" is off, the parameter will be ignored. Value`http_2xx` / `http_3xx` / `http_4xx` / `http_5xx`.
* `ssl_certificate_id` - (Optinal) Security certificate ID.
## Attributes Reference
@ -91,4 +138,4 @@ The following attributes are exported:
* `internet_charge_type` - The internet_charge_type of the load balancer.
* `bandwidth` - The bandwidth of the load balancer.
* `vswitch_id` - The VSwitch ID of the load balancer. Only available on SLB launched in a VPC.
* `address` - The IP address of the load balancer.
* `address` - The IP address of the load balancer.

View File

@ -6,20 +6,20 @@ description: |-
Provides an Application Load Banlancer Attachment resource.
---
# alicloud_slb_attachment
# alicloud\_slb\_attachment
Provides an Application Load Balancer Attachment resource.
## Example Usage
```hcl
```
# Create a new load balancer attachment for classic
resource "alicloud_slb" "default" {
# ...
# Other parameters...
}
resource "alicloud_instance" "default" {
# ...
# Other parameters...
}
resource "alicloud_slb_attachment" "default" {

View File

@ -0,0 +1,61 @@
---
layout: "alicloud"
page_title: "Alicloud: alicloud_snat_entry"
sidebar_current: "docs-alicloud-resource-vpc"
description: |-
Provides a Alicloud snat resource.
---
# alicloud\_snat
Provides a snat resource.
## Example Usage
Basic Usage
```
resource "alicloud_vpc" "foo" {
...
}
resource "alicloud_vswitch" "foo" {
...
}
resource "alicloud_nat_gateway" "foo" {
vpc_id = "${alicloud_vpc.foo.id}"
spec = "Small"
name = "test_foo"
bandwidth_packages = [
{
ip_count = 2
bandwidth = 5
zone = ""
},
{
ip_count = 1
bandwidth = 6
zone = "cn-beijing-b"
}
]
depends_on = [
"alicloud_vswitch.foo"
]
}
resource "alicloud_snat_entry" "foo" {
snat_table_id = "${alicloud_nat_gateway.foo.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.foo.id}"
snat_ip = "${alicloud_nat_gateway.foo.bandwidth_packages.0.public_ip_addresses}"
}
```
## Argument Reference
The following arguments are supported:
* `snat_table_id` - (Required, Forces new resource) The value can get from `alicloud_nat_gateway` Attributes "snat_table_ids".
* `source_vswitch_id` - (Required, Forces new resource) The vswitch ID.
* `snat_ip` - (Required) The SNAT ip address, the ip must along bandwidth package public ip which `alicloud_nat_gateway` argument `bandwidth_packages`.

View File

@ -16,13 +16,12 @@ Provides a VPC resource.
Basic Usage
```hcl
```
resource "alicloud_vpc" "vpc" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
}
```
## Argument Reference
The following arguments are supported:

View File

@ -14,7 +14,7 @@ Provides a route entry resource.
Basic Usage
```hcl
```
resource "alicloud_vpc" "vpc" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"
@ -29,7 +29,7 @@ resource "alicloud_route_entry" "default" {
}
resource "alicloud_instance" "snat" {
# ...
// ...
}
```
## Argument Reference

View File

@ -6,7 +6,7 @@ description: |-
Provides a Alicloud VPC switch resource.
---
# alicloud_vswitch
# alicloud\_vswitch
Provides a VPC switch resource.
@ -14,7 +14,7 @@ Provides a VPC switch resource.
Basic Usage
```hcl
```
resource "alicloud_vpc" "vpc" {
name = "tf_test_foo"
cidr_block = "172.16.0.0/12"

View File

@ -1,75 +1,122 @@
<% wrap_layout :inner do %>
<% content_for :sidebar do %>
<ul class="nav docs-sidenav">
<li>
<a class="back" href="/docs/providers/index.html">All Providers</a>
</li>
<% content_for :sidebar do %>
<div class="docs-sidebar hidden-print affix-top" role="complementary">
<ul class="nav docs-sidenav">
<li<%= sidebar_current("docs-home") %>>
<a href="/docs/providers/index.html">&laquo; Documentation Home</a>
</li>
<li<%= sidebar_current("docs-alicloud-index") %>>
<a class="back" href="/docs/providers/alicloud/index.html">Alicloud Provider</a>
</li>
<li<%= sidebar_current("docs-alicloud-index") %>>
<a href="/docs/providers/alicloud/index.html">Alicloud Provider</a>
</li>
<h4>Data Sources</h4>
<li<%= sidebar_current(/^docs-alicloud-datasource/) %>>
<a href="#">Data Sources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-alicloud-datasource-instance-types") %>>
<a href="/docs/providers/alicloud/d/instance_types.html">alicloud_instance_types</a>
</li>
<li<%= sidebar_current("docs-alicloud-datasource-images") %>>
<a href="/docs/providers/alicloud/d/images.html">alicloud_images</a>
</li>
<li<%= sidebar_current("docs-alicloud-datasource-zones") %>>
<a href="/docs/providers/alicloud/d/zones.html">alicloud_zones</a>
</li>
</ul>
</li>
<li<%= sidebar_current("docs-alicloud-datasource-images") %>>
<a href="/docs/providers/alicloud/d/images.html">alicloud_images</a>
</li>
<li<%= sidebar_current("docs-alicloud-datasource-instance-types") %>>
<a href="/docs/providers/alicloud/d/instance_types.html">alicloud_instance_types</a>
</li>
<li<%= sidebar_current("docs-alicloud-datasource-regions") %>>
<a href="/docs/providers/alicloud/d/regions.html">alicloud_regions</a>
</li>
<li<%= sidebar_current("docs-alicloud-datasource-zones") %>>
<a href="/docs/providers/alicloud/d/zones.html">alicloud_zones</a>
</li>
<li<%= sidebar_current(/^docs-alicloud-resource-ecs/) %>>
<a href="#">ECS Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-alicloud-resource-disk") %>>
<a href="/docs/providers/alicloud/r/disk.html">alicloud_disk</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-disk-attachment") %>>
<a href="/docs/providers/alicloud/r/disk_attachment.html">alicloud_disk_attachment</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-instance") %>>
<a href="/docs/providers/alicloud/r/instance.html">alicloud_instance</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-eip") %>>
<a href="/docs/providers/alicloud/r/eip.html">alicloud_eip</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-eip-association") %>>
<a href="/docs/providers/alicloud/r/eip_association.html">alicloud_eip_association</a>
</li>
</ul>
</li>
<h4>Resources</h4>
<li<%= sidebar_current(/^docs-alicloud-resource-slb/) %>>
<a href="#">SLB Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-alicloud-resource-slb") %>>
<a href="/docs/providers/alicloud/r/slb.html">alicloud_slb</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-slb-attachment") %>>
<a href="/docs/providers/alicloud/r/slb_attachment.html">alicloud_slb_attachment</a>
</li>
</ul>
</li>
<li<%= sidebar_current("docs-alicloud-resource-db-instance") %>>
<a href="/docs/providers/alicloud/r/db_instance.html">alicloud_db_instance</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-disk.") %>>
<a href="/docs/providers/alicloud/r/disk.html">alicloud_disk</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-disk-attachment") %>>
<a href="/docs/providers/alicloud/r/disk_attachment.html">alicloud_disk_attachment</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-eip.") %>>
<a href="/docs/providers/alicloud/r/eip.html">alicloud_eip</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-eip-association") %>>
<a href="/docs/providers/alicloud/r/eip_association.html">alicloud_eip_association</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-instance") %>>
<a href="/docs/providers/alicloud/r/instance.html">alicloud_instance</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-nat-gateway") %>>
<a href="/docs/providers/alicloud/r/nat_gateway.html">alicloud_nat_gateway</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-security-group.") %>>
<a href="/docs/providers/alicloud/r/security_group.html">alicloud_security_group</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-security-group-rule") %>>
<a href="/docs/providers/alicloud/r/security_group_rule.html">alicloud_security_group_rule</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-slb.") %>>
<a href="/docs/providers/alicloud/r/slb.html">alicloud_slb</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-slb-attachment") %>>
<a href="/docs/providers/alicloud/r/slb_attachment.html">alicloud_slb_attachment</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-vpc") %>>
<a href="/docs/providers/alicloud/r/vpc.html">alicloud_vpc</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-route-entry") %>>
<a href="/docs/providers/alicloud/r/vroute_entry.html">alicloud_vroute_entry</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-vswitch") %>>
<a href="/docs/providers/alicloud/r/vswitch.html">alicloud_vswitch</a>
</li>
</ul>
<% end %>
<li<%= sidebar_current(/^docs-alicloud-resource-vpc/) %>>
<a href="#">VPC Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-alicloud-resource-vpc") %>>
<a href="/docs/providers/alicloud/r/vpc.html">alicloud_vpc</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-vswitch") %>>
<a href="/docs/providers/alicloud/r/vswitch.html">alicloud_vswitch</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-route-entry") %>>
<a href="/docs/providers/alicloud/r/vroute_entry.html">alicloud_route_entry</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-security-group") %>>
<a href="/docs/providers/alicloud/r/security_group.html">alicloud_security_group</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-security-group-rule") %>>
<a href="/docs/providers/alicloud/r/security_group_rule.html">alicloud_security_group_rule</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-nat-gateway") %>>
<a href="/docs/providers/alicloud/r/nat_gateway.html">alicloud_nat_gateway</a>
</li>
</ul>
</li>
<%= yield %>
<li<%= sidebar_current(/^docs-alicloud-resource-rds/) %>>
<a href="#">RDS Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-alicloud-resource-rds") %>>
<a href="/docs/providers/alicloud/r/db_instance.html">alicloud_rds</a>
</li>
</ul>
</li>
<li<%= sidebar_current(/^docs-alicloud-resource-ess/) %>>
<a href="#">ESS Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-alicloud-resource-ess") %>>
<a href="/docs/providers/alicloud/r/ess_scaling_group.html">alicloud_ess_scaling_group</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-ess") %>>
<a href="/docs/providers/alicloud/r/ess_scaling_configuration.html">alicloud_ess_scaling_configuration</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-ess") %>>
<a href="/docs/providers/alicloud/r/ess_scaling_rule.html">alicloud_ess_scaling_rule</a>
</li>
<li<%= sidebar_current("docs-alicloud-resource-ess") %>>
<a href="/docs/providers/alicloud/r/ess_schedule.html">alicloud_ess_schedule</a>
</li>
</ul>
</li>
</ul>
</div>
<% end %>
<%= yield %>
<% end %>