create temporary ACG for VPC
This commit is contained in:
parent
3a11352dfa
commit
74434b3c3e
|
@ -50,6 +50,7 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||||
NewStepValidateTemplate(conn, ui, &b.config),
|
NewStepValidateTemplate(conn, ui, &b.config),
|
||||||
NewStepCreateLoginKey(conn, ui, &b.config),
|
NewStepCreateLoginKey(conn, ui, &b.config),
|
||||||
multistep.If(b.config.SupportVPC, NewStepCreateInitScript(conn, ui, &b.config)),
|
multistep.If(b.config.SupportVPC, NewStepCreateInitScript(conn, ui, &b.config)),
|
||||||
|
multistep.If(b.config.SupportVPC, NewStepCreateAccessControlGroup(conn, ui, &b.config)),
|
||||||
NewStepCreateServerInstance(conn, ui, &b.config),
|
NewStepCreateServerInstance(conn, ui, &b.config),
|
||||||
NewStepCreateBlockStorage(conn, ui, &b.config),
|
NewStepCreateBlockStorage(conn, ui, &b.config),
|
||||||
NewStepGetRootPassword(conn, ui, &b.config),
|
NewStepGetRootPassword(conn, ui, &b.config),
|
||||||
|
|
|
@ -54,16 +54,19 @@ type Config struct {
|
||||||
// (default: Korea)
|
// (default: Korea)
|
||||||
Region string `mapstructure:"region" required:"false"`
|
Region string `mapstructure:"region" required:"false"`
|
||||||
RegionCode string `mapstructure:"region_code" required:"false"`
|
RegionCode string `mapstructure:"region_code" required:"false"`
|
||||||
|
// Deprecated
|
||||||
|
AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no" required:"false"`
|
||||||
// This is used to allow
|
// This is used to allow
|
||||||
// winrm access when you create a Windows server. An ACG that specifies an
|
// winrm access when you create a Windows server. An ACG that specifies an
|
||||||
// access source (0.0.0.0/0) and allowed port (5985) must be created in
|
// access source (0.0.0.0/0) and allowed port (5985) must be created in
|
||||||
// advance.
|
// advance if you use CLASSIC env. If this field is left blank,
|
||||||
AccessControlGroupConfigurationNo string `mapstructure:"access_control_group_configuration_no" required:"false"`
|
// Packer will create temporary ACG for automatically in VPC environment.
|
||||||
// Whether to use VPC. By default, the value is false on "public" site. If you want to use VPC environment. Please set this value true.
|
AccessControlGroupNo string `mapstructure:"access_control_group_no" required:"false"`
|
||||||
SupportVPC bool `mapstructure:"support_vpc" required:"false"`
|
SupportVPC bool `mapstructure:"support_vpc" required:"false"`
|
||||||
// The ID of the associated Subnet
|
// The ID of the Subnet where you want to place the Server Instance. If this field is left blank, Packer will try to get the Public Subnet ID from the `vpc_no`.
|
||||||
SubnetNo string `mapstructure:"subnet_no" required:"false"`
|
SubnetNo string `mapstructure:"subnet_no" required:"false"`
|
||||||
// The ID of the VPC where you want to place the Server Instance
|
// The ID of the VPC where you want to place the Server Instance. If this field is left blank, Packer will try to get the VPC ID from the `subnet_no`.
|
||||||
|
// (You are required to least one between two parameters if u want using VPC environment: `vpc_no` or `subnet_no`)
|
||||||
VpcNo string `mapstructure:"vpc_no" required:"false"`
|
VpcNo string `mapstructure:"vpc_no" required:"false"`
|
||||||
|
|
||||||
Comm communicator.Config `mapstructure:",squash"`
|
Comm communicator.Config `mapstructure:",squash"`
|
||||||
|
@ -141,14 +144,18 @@ func (c *Config) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
errs = packersdk.MultiErrorAppend(errs, errors.New("if `user_data` field is set, length of UserData should be max 21847"))
|
errs = packersdk.MultiErrorAppend(errs, errors.New("if `user_data` field is set, length of UserData should be max 21847"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Comm.Type == "winrm" && c.AccessControlGroupConfigurationNo == "" {
|
if c.AccessControlGroupConfigurationNo != "" {
|
||||||
errs = packersdk.MultiErrorAppend(errs, errors.New("if Communicator is winrm, `access_control_group_configuration_no` (allow 5986 port) is required"))
|
errs = packersdk.MultiErrorAppend(errs, errors.New("`access_control_group_configuration_no` is deprecated, please use `access_control_group_no` instead"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.VpcNo != "" || c.SubnetNo != "" {
|
if c.VpcNo != "" || c.SubnetNo != "" {
|
||||||
c.SupportVPC = true
|
c.SupportVPC = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Comm.Type == "winrm" && c.AccessControlGroupNo == "" && !c.SupportVPC {
|
||||||
|
errs = packersdk.MultiErrorAppend(errs, errors.New("if Communicator is winrm, `access_control_group_no` (allow 5986 port) is required in `CLASSIC` environment"))
|
||||||
|
}
|
||||||
|
|
||||||
if errs != nil && len(errs.Errors) > 0 {
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
return warnings, errs
|
return warnings, errs
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ type FlatConfig struct {
|
||||||
Region *string `mapstructure:"region" required:"false" cty:"region" hcl:"region"`
|
Region *string `mapstructure:"region" required:"false" cty:"region" hcl:"region"`
|
||||||
RegionCode *string `mapstructure:"region_code" required:"false" cty:"region_code" hcl:"region_code"`
|
RegionCode *string `mapstructure:"region_code" required:"false" cty:"region_code" hcl:"region_code"`
|
||||||
AccessControlGroupConfigurationNo *string `mapstructure:"access_control_group_configuration_no" required:"false" cty:"access_control_group_configuration_no" hcl:"access_control_group_configuration_no"`
|
AccessControlGroupConfigurationNo *string `mapstructure:"access_control_group_configuration_no" required:"false" cty:"access_control_group_configuration_no" hcl:"access_control_group_configuration_no"`
|
||||||
|
AccessControlGroupNo *string `mapstructure:"access_control_group_no" required:"false" cty:"access_control_group_no" hcl:"access_control_group_no"`
|
||||||
SupportVPC *bool `mapstructure:"support_vpc" required:"false" cty:"support_vpc" hcl:"support_vpc"`
|
SupportVPC *bool `mapstructure:"support_vpc" required:"false" cty:"support_vpc" hcl:"support_vpc"`
|
||||||
SubnetNo *string `mapstructure:"subnet_no" required:"false" cty:"subnet_no" hcl:"subnet_no"`
|
SubnetNo *string `mapstructure:"subnet_no" required:"false" cty:"subnet_no" hcl:"subnet_no"`
|
||||||
VpcNo *string `mapstructure:"vpc_no" required:"false" cty:"vpc_no" hcl:"vpc_no"`
|
VpcNo *string `mapstructure:"vpc_no" required:"false" cty:"vpc_no" hcl:"vpc_no"`
|
||||||
|
@ -118,6 +119,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||||
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
|
||||||
"region_code": &hcldec.AttrSpec{Name: "region_code", Type: cty.String, Required: false},
|
"region_code": &hcldec.AttrSpec{Name: "region_code", Type: cty.String, Required: false},
|
||||||
"access_control_group_configuration_no": &hcldec.AttrSpec{Name: "access_control_group_configuration_no", Type: cty.String, Required: false},
|
"access_control_group_configuration_no": &hcldec.AttrSpec{Name: "access_control_group_configuration_no", Type: cty.String, Required: false},
|
||||||
|
"access_control_group_no": &hcldec.AttrSpec{Name: "access_control_group_no", Type: cty.String, Required: false},
|
||||||
"support_vpc": &hcldec.AttrSpec{Name: "support_vpc", Type: cty.Bool, Required: false},
|
"support_vpc": &hcldec.AttrSpec{Name: "support_vpc", Type: cty.Bool, Required: false},
|
||||||
"subnet_no": &hcldec.AttrSpec{Name: "subnet_no", Type: cty.String, Required: false},
|
"subnet_no": &hcldec.AttrSpec{Name: "subnet_no", Type: cty.String, Required: false},
|
||||||
"vpc_no": &hcldec.AttrSpec{Name: "vpc_no", Type: cty.String, Required: false},
|
"vpc_no": &hcldec.AttrSpec{Name: "vpc_no", Type: cty.String, Required: false},
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
package ncloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/ncloud"
|
||||||
|
"github.com/NaverCloudPlatform/ncloud-sdk-go-v2/services/vserver"
|
||||||
|
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||||
|
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StepCreateAccessControlGroup struct {
|
||||||
|
Conn *NcloudAPIClient
|
||||||
|
GetAccessControlGroup func(acgNo string) (*vserver.AccessControlGroup, error)
|
||||||
|
CreateAccessControlGroup func() (string, error)
|
||||||
|
AddAccessControlGroupRule func(acgNo string) error
|
||||||
|
Say func(message string)
|
||||||
|
Error func(e error)
|
||||||
|
Config *Config
|
||||||
|
createdAcgNo string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStepCreateAccessControlGroup(conn *NcloudAPIClient, ui packersdk.Ui, config *Config) *StepCreateAccessControlGroup {
|
||||||
|
var step = &StepCreateAccessControlGroup{
|
||||||
|
Conn: conn,
|
||||||
|
Say: func(message string) { ui.Say(message) },
|
||||||
|
Error: func(e error) { ui.Error(e.Error()) },
|
||||||
|
Config: config,
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.SupportVPC {
|
||||||
|
step.GetAccessControlGroup = step.getVpcAccessControlGroup
|
||||||
|
step.CreateAccessControlGroup = step.createVpcAccessControlGroup
|
||||||
|
step.AddAccessControlGroupRule = step.addVpcAccessControlGroupRule
|
||||||
|
}
|
||||||
|
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCreateAccessControlGroup) createVpcAccessControlGroup() (string, error) {
|
||||||
|
reqParam := &vserver.CreateAccessControlGroupRequest{
|
||||||
|
RegionCode: &s.Config.RegionCode,
|
||||||
|
AccessControlGroupName: &s.Config.ServerImageName,
|
||||||
|
AccessControlGroupDescription: ncloud.String("Temporary ACG for packer"),
|
||||||
|
VpcNo: &s.Config.VpcNo,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.Conn.vserver.V2Api.CreateAccessControlGroup(reqParam)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp != nil && *resp.TotalRows > 0 {
|
||||||
|
return *resp.AccessControlGroupList[0].AccessControlGroupNo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCreateAccessControlGroup) addVpcAccessControlGroupRule(acgNo string) error {
|
||||||
|
_, err := s.Conn.vserver.V2Api.AddAccessControlGroupInboundRule(&vserver.AddAccessControlGroupInboundRuleRequest{
|
||||||
|
RegionCode: &s.Config.RegionCode,
|
||||||
|
AccessControlGroupNo: &acgNo,
|
||||||
|
VpcNo: &s.Config.VpcNo,
|
||||||
|
AccessControlGroupRuleList: []*vserver.AddAccessControlGroupRuleParameter{
|
||||||
|
{
|
||||||
|
IpBlock: ncloud.String("0.0.0.0/0"),
|
||||||
|
PortRange: ncloud.String("22"),
|
||||||
|
ProtocolTypeCode: ncloud.String("TCP"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IpBlock: ncloud.String("0.0.0.0/0"),
|
||||||
|
PortRange: ncloud.String("3389"),
|
||||||
|
ProtocolTypeCode: ncloud.String("TCP"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IpBlock: ncloud.String("0.0.0.0/0"),
|
||||||
|
PortRange: ncloud.String("5985"),
|
||||||
|
ProtocolTypeCode: ncloud.String("TCP"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.Conn.vserver.V2Api.AddAccessControlGroupOutboundRule(&vserver.AddAccessControlGroupOutboundRuleRequest{
|
||||||
|
RegionCode: &s.Config.RegionCode,
|
||||||
|
AccessControlGroupNo: &acgNo,
|
||||||
|
VpcNo: &s.Config.VpcNo,
|
||||||
|
AccessControlGroupRuleList: []*vserver.AddAccessControlGroupRuleParameter{
|
||||||
|
{
|
||||||
|
IpBlock: ncloud.String("0.0.0.0/0"),
|
||||||
|
ProtocolTypeCode: ncloud.String("ICMP"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IpBlock: ncloud.String("0.0.0.0/0"),
|
||||||
|
PortRange: ncloud.String("1-65535"),
|
||||||
|
ProtocolTypeCode: ncloud.String("TCP"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
IpBlock: ncloud.String("0.0.0.0/0"),
|
||||||
|
PortRange: ncloud.String("1-65535"),
|
||||||
|
ProtocolTypeCode: ncloud.String("UDP"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCreateAccessControlGroup) deleteVpcAccessControlGroup(id string) error {
|
||||||
|
reqParam := &vserver.DeleteAccessControlGroupRequest{
|
||||||
|
RegionCode: &s.Config.RegionCode,
|
||||||
|
VpcNo: &s.Config.VpcNo,
|
||||||
|
AccessControlGroupNo: ncloud.String(id),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := s.Conn.vserver.V2Api.DeleteAccessControlGroup(reqParam)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCreateAccessControlGroup) getVpcAccessControlGroup(id string) (*vserver.AccessControlGroup, error) {
|
||||||
|
reqParam := &vserver.GetAccessControlGroupDetailRequest{
|
||||||
|
RegionCode: &s.Config.RegionCode,
|
||||||
|
AccessControlGroupNo: ncloud.String(id),
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := s.Conn.vserver.V2Api.GetAccessControlGroupDetail(reqParam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp != nil && *resp.TotalRows > 0 {
|
||||||
|
return resp.AccessControlGroupList[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCreateAccessControlGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
s.Say("Create temporary ACG")
|
||||||
|
if len(s.Config.AccessControlGroupNo) > 0 {
|
||||||
|
acg, err := s.GetAccessControlGroup(s.Config.AccessControlGroupNo)
|
||||||
|
if err != nil || acg == nil {
|
||||||
|
err := fmt.Errorf("couldn't find specified ACG: %s", err)
|
||||||
|
state.Put("error", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Using specified ACG: %v", s.Config.AccessControlGroupNo)
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
acgNo, err := s.CreateAccessControlGroup()
|
||||||
|
s.Say(fmt.Sprintf("Creating temporary ACG [%s]", acgNo))
|
||||||
|
if err != nil || len(acgNo) == 0 {
|
||||||
|
err := fmt.Errorf("couldn't create ACG for VPC: %s", err)
|
||||||
|
state.Put("error", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
s.createdAcgNo = acgNo
|
||||||
|
|
||||||
|
s.Say(fmt.Sprintf("Creating temporary rules ACG [%s]", acgNo))
|
||||||
|
err = s.AddAccessControlGroupRule(acgNo)
|
||||||
|
if err != nil {
|
||||||
|
err := fmt.Errorf("couldn't create ACG rules for SSH or winrm: %s", err)
|
||||||
|
state.Put("error", err)
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
state.Put("access_control_group_no", acgNo)
|
||||||
|
|
||||||
|
return processStepResult(err, s.Error, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StepCreateAccessControlGroup) Cleanup(state multistep.StateBag) {
|
||||||
|
if s.createdAcgNo == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := s.deleteVpcAccessControlGroup(s.createdAcgNo)
|
||||||
|
if err != nil {
|
||||||
|
s.Error(fmt.Errorf("error cleaning up ACG. Please delete the ACG manually: err: %s; ACG No: %s", err, s.createdAcgNo))
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Say("Clean up temporary ACG")
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package ncloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStepCreateAccessControlGroupShouldFailIfOperationCreateAccessControlGroupFails(t *testing.T) {
|
||||||
|
var testSubject = &StepCreateAccessControlGroup{
|
||||||
|
CreateAccessControlGroup: func() (string, error) { return "", fmt.Errorf("!! Unit Test FAIL !!") },
|
||||||
|
Say: func(message string) {},
|
||||||
|
Error: func(e error) {},
|
||||||
|
Config: &Config{
|
||||||
|
Region: "Korea",
|
||||||
|
SupportVPC: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
stateBag := createTestStateBagStepCreateAccessControlGroup()
|
||||||
|
|
||||||
|
var result = testSubject.Run(context.Background(), stateBag)
|
||||||
|
|
||||||
|
if result != multistep.ActionHalt {
|
||||||
|
t.Fatalf("Expected the step to return 'ActionHalt', but got '%d'.", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := stateBag.GetOk("error"); ok == false {
|
||||||
|
t.Fatal("Expected the step to set stateBag['Error'], but it was not.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStepCreateAccessControlGroupShouldPassIfOperationCreateAccessControlGroupPasses(t *testing.T) {
|
||||||
|
var testSubject = &StepCreateAccessControlGroup{
|
||||||
|
CreateAccessControlGroup: func() (string, error) { return "123", nil },
|
||||||
|
AddAccessControlGroupRule: func(acgNo string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Say: func(message string) {},
|
||||||
|
Error: func(error) {},
|
||||||
|
Config: &Config{
|
||||||
|
Region: "Korea",
|
||||||
|
SupportVPC: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
stateBag := createTestStateBagStepCreateAccessControlGroup()
|
||||||
|
|
||||||
|
var result = testSubject.Run(context.Background(), stateBag)
|
||||||
|
|
||||||
|
if result != multistep.ActionContinue {
|
||||||
|
t.Fatalf("Expected the step to return 'ActionContinue', but got '%d'.", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := stateBag.GetOk("error"); ok == true {
|
||||||
|
t.Fatalf("Expected the step to not set stateBag['Error'], but it was.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTestStateBagStepCreateAccessControlGroup() multistep.StateBag {
|
||||||
|
stateBag := new(multistep.BasicStateBag)
|
||||||
|
|
||||||
|
return stateBag
|
||||||
|
}
|
|
@ -92,8 +92,10 @@ func (s *StepCreateInitScript) deleteVpcInitScript(initScriptNo string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepCreateInitScript) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
func (s *StepCreateInitScript) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
|
if len(s.Config.UserData) == 0 && len(s.Config.UserDataFile) == 0 {
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
s.Say("Create Init script")
|
s.Say("Create Init script")
|
||||||
|
|
||||||
initScriptNo, err := s.CreateInitScript()
|
initScriptNo, err := s.CreateInitScript()
|
||||||
if err == nil && initScriptNo != "" {
|
if err == nil && initScriptNo != "" {
|
||||||
state.Put("init_script_no", initScriptNo)
|
state.Put("init_script_no", initScriptNo)
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestStepCreateInitScriptShouldFailIfOperationCreateInitScriptFails(t *testi
|
||||||
Say: func(message string) {},
|
Say: func(message string) {},
|
||||||
Error: func(e error) {},
|
Error: func(e error) {},
|
||||||
Config: &Config{
|
Config: &Config{
|
||||||
Region: "KR",
|
Region: "Korea",
|
||||||
SupportVPC: true,
|
SupportVPC: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func TestStepCreateInitScriptShouldPassIfOperationCreateInitScriptPasses(t *test
|
||||||
Say: func(message string) {},
|
Say: func(message string) {},
|
||||||
Error: func(e error) {},
|
Error: func(e error) {},
|
||||||
Config: &Config{
|
Config: &Config{
|
||||||
Region: "KR",
|
Region: "Korea",
|
||||||
SupportVPC: true,
|
SupportVPC: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,8 @@ func (s *StepCreateServerInstance) createClassicServerInstance(loginKeyName stri
|
||||||
reqParams.UserData = ncloud.String(string(contents))
|
reqParams.UserData = ncloud.String(string(contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Config.AccessControlGroupConfigurationNo != "" {
|
if s.Config.AccessControlGroupNo != "" {
|
||||||
reqParams.AccessControlGroupConfigurationNoList = []*string{&s.Config.AccessControlGroupConfigurationNo}
|
reqParams.AccessControlGroupConfigurationNoList = []*string{&s.Config.AccessControlGroupNo}
|
||||||
}
|
}
|
||||||
|
|
||||||
serverInstanceList, err := s.Conn.server.V2Api.CreateServerInstances(reqParams)
|
serverInstanceList, err := s.Conn.server.V2Api.CreateServerInstances(reqParams)
|
||||||
|
@ -111,14 +111,10 @@ func (s *StepCreateServerInstance) createVpcServerInstance(loginKeyName string,
|
||||||
initScriptNo = v.(string)
|
initScriptNo = v.(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Config.AccessControlGroupConfigurationNo != "" {
|
if s.Config.AccessControlGroupNo != "" {
|
||||||
acgNo = s.Config.AccessControlGroupConfigurationNo
|
acgNo = s.Config.AccessControlGroupNo
|
||||||
} else {
|
} else {
|
||||||
acgNo, err = s.getDefaultAccessControlGroup(s.Config.VpcNo)
|
acgNo = state.Get("access_control_group_no").(string)
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reqParams := &vserver.CreateServerInstancesRequest{
|
reqParams := &vserver.CreateServerInstancesRequest{
|
||||||
|
@ -158,31 +154,6 @@ func (s *StepCreateServerInstance) createVpcServerInstance(loginKeyName string,
|
||||||
return s.serverInstanceNo, nil
|
return s.serverInstanceNo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StepCreateServerInstance) getDefaultAccessControlGroup(id string) (string, error) {
|
|
||||||
reqParams := &vserver.GetAccessControlGroupListRequest{
|
|
||||||
RegionCode: &s.Config.RegionCode,
|
|
||||||
VpcNo: ncloud.String(id),
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := s.Conn.vserver.V2Api.GetAccessControlGroupList(reqParams)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp == nil || len(resp.AccessControlGroupList) == 0 {
|
|
||||||
return "", fmt.Errorf("no matching Access Control Group found")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, i := range resp.AccessControlGroupList {
|
|
||||||
if *i.IsDefault {
|
|
||||||
return *i.AccessControlGroupNo, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", fmt.Errorf("no matching default Access Control Group found")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StepCreateServerInstance) getClassicServerInstance() (string, string, error) {
|
func (s *StepCreateServerInstance) getClassicServerInstance() (string, string, error) {
|
||||||
reqParams := &server.GetServerInstanceListRequest{
|
reqParams := &server.GetServerInstanceListRequest{
|
||||||
ServerInstanceNoList: []*string{&s.serverInstanceNo},
|
ServerInstanceNoList: []*string{&s.serverInstanceNo},
|
||||||
|
@ -219,7 +190,7 @@ func (s *StepCreateServerInstance) getVpcServerInstance() (string, string, error
|
||||||
|
|
||||||
func (s *StepCreateServerInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
func (s *StepCreateServerInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||||
s.Say("Create Server Instance")
|
s.Say("Create Server Instance")
|
||||||
var loginKey = state.Get("login_key").(*LoginKey)
|
loginKey := state.Get("login_key").(*LoginKey)
|
||||||
|
|
||||||
feeSystemTypeCode := "MTRAT"
|
feeSystemTypeCode := "MTRAT"
|
||||||
if _, ok := state.GetOk("fee_system_type_code"); ok {
|
if _, ok := state.GetOk("fee_system_type_code"); ok {
|
||||||
|
|
|
@ -31,9 +31,8 @@ Platform](https://www.ncloud.com/).
|
||||||
- `server_image_product_code` (string) - Product code of an image to create.
|
- `server_image_product_code` (string) - Product code of an image to create.
|
||||||
(member_server_image_no is required if not specified)
|
(member_server_image_no is required if not specified)
|
||||||
|
|
||||||
- `server_product_code` (string) - Product (spec) code to create.
|
|
||||||
|
|
||||||
### Optional:
|
### Optional:
|
||||||
|
- `server_product_code` (string) - Product (spec) code to create.
|
||||||
|
|
||||||
- `vpc_no` (string) - The ID of the VPC where you want to place the Server Instance. If this field is left blank, Packer will try to get the VPC ID from the `subnet_no`.
|
- `vpc_no` (string) - The ID of the VPC where you want to place the Server Instance. If this field is left blank, Packer will try to get the VPC ID from the `subnet_no`.
|
||||||
(You are required to least one between two parameters if u want using VPC environment: `vpc_no` or `subnet_no`)
|
(You are required to least one between two parameters if u want using VPC environment: `vpc_no` or `subnet_no`)
|
||||||
|
@ -51,10 +50,10 @@ Platform](https://www.ncloud.com/).
|
||||||
- `block_storage_size` (number) - You can add block storage ranging from 10
|
- `block_storage_size` (number) - You can add block storage ranging from 10
|
||||||
GB to 2000 GB, in increments of 10 GB.
|
GB to 2000 GB, in increments of 10 GB.
|
||||||
|
|
||||||
- `access_control_group_configuration_no` (string) - This is used to allow
|
- `access_control_group_no` (string) - This is used to allow
|
||||||
winrm access when you create a Windows server. An ACG that specifies an
|
winrm access when you create a Windows server. An ACG that specifies an
|
||||||
access source (`0.0.0.0/0`) and allowed port (5985) must be created in
|
access source (`0.0.0.0/0`) and allowed port (5985) must be created in
|
||||||
advance.
|
advance if you use CLASSIC env. If this field is left blank, Packer will create temporary ACG for automatically in VPC environment.
|
||||||
|
|
||||||
- `user_data` (string) - User data to apply when launching the instance. Note
|
- `user_data` (string) - User data to apply when launching the instance. Note
|
||||||
that you need to be careful about escaping characters due to the templates
|
that you need to be careful about escaping characters due to the templates
|
||||||
|
@ -104,6 +103,7 @@ source "ncloud" "example-windows" {
|
||||||
subnet_no = "{{YOUR_SUBNET_ID}}" // Remove this if you use CLASSIC environment.
|
subnet_no = "{{YOUR_SUBNET_ID}}" // Remove this if you use CLASSIC environment.
|
||||||
communicator = "winrm"
|
communicator = "winrm"
|
||||||
winrm_username = "Administrator"
|
winrm_username = "Administrator"
|
||||||
|
# access_control_group_no = "{{YOUR_ACG_ID}}" // Specific ACG ID allowed port (5985) if you use CLASSIC environment.
|
||||||
}
|
}
|
||||||
|
|
||||||
build {
|
build {
|
||||||
|
@ -111,7 +111,7 @@ build {
|
||||||
|
|
||||||
provisioner "powershell" {
|
provisioner "powershell" {
|
||||||
inline = [
|
inline = [
|
||||||
"$Env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /shutdown /quiet /mode:vm \"/unattend:C:\\Program Files (x86)\\example\\nserver64.xml\" "
|
"Write-Output 1,2,3 | Measure-Object"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ build {
|
||||||
{
|
{
|
||||||
"type": "powershell",
|
"type": "powershell",
|
||||||
"inline": [
|
"inline": [
|
||||||
"$Env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /shutdown /quiet /mode:vm \"/unattend:C:\\Program Files (x86)\\NBP\\nserver64.xml\" "
|
"Write-Output 1,2,3 | Measure-Object"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -195,7 +195,7 @@ build {
|
||||||
|
|
||||||
provisioner "shell" {
|
provisioner "shell" {
|
||||||
inline = [
|
inline = [
|
||||||
"sleep 30", "yum install redis.x86_64 -y"
|
"echo Connected via SSM at '${build.User}@${build.Host}:${build.Port}'"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ build {
|
||||||
{
|
{
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"inline": [
|
"inline": [
|
||||||
"sleep 30", "yum install redis.x86_64 -y"
|
"echo Connected via SSM at '${build.User}@${build.Host}:${build.Port}'"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -29,12 +29,15 @@
|
||||||
|
|
||||||
- `region_code` (string) - Region Code
|
- `region_code` (string) - Region Code
|
||||||
|
|
||||||
- `access_control_group_configuration_no` (string) - This is used to allow
|
- `access_control_group_configuration_no` (string) - Deprecated
|
||||||
|
|
||||||
|
- `access_control_group_no` (string) - This is used to allow
|
||||||
winrm access when you create a Windows server. An ACG that specifies an
|
winrm access when you create a Windows server. An ACG that specifies an
|
||||||
access source (0.0.0.0/0) and allowed port (5985) must be created in
|
access source (0.0.0.0/0) and allowed port (5985) must be created in
|
||||||
advance.
|
advance if you use CLASSIC env. If this field is left blank,
|
||||||
|
Packer will create temporary ACG for automatically in VPC environment.
|
||||||
|
|
||||||
|
- `subnet_no` (string) - The ID of the Subnet where you want to place the Server Instance. If this field is left blank, Packer will try to get the Public Subnet ID from the `vpc_no`.
|
||||||
|
|
||||||
- `vpc_no` (string) - The ID of the VPC where you want to place the Server Instance. If this field is left blank, Packer will try to get the VPC ID from the `subnet_no`.
|
- `vpc_no` (string) - The ID of the VPC where you want to place the Server Instance. If this field is left blank, Packer will try to get the VPC ID from the `subnet_no`.
|
||||||
(You are required to least one between two parameters if u want using VPC environment: `vpc_no` or `subnet_no`)
|
(You are required to least one between two parameters if u want using VPC environment: `vpc_no` or `subnet_no`)
|
||||||
|
|
||||||
- `subnet_no` (string) - The ID of the Subnet where you want to place the Server Instance. If this field is left blank, Packer will try to get the Public Subnet ID from the `vpc_no`.
|
|
||||||
|
|
Loading…
Reference in New Issue