Merge pull request #4425 from mitchellh/sg

builder/amazon: fix when using non-existant security_group_id
This commit is contained in:
Matthew Hooker 2017-01-18 15:26:39 -08:00 committed by GitHub
commit 2c2eaf89f5
2 changed files with 65 additions and 58 deletions

View File

@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/private/waiter"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
@ -23,8 +22,9 @@ type StepRunSourceInstance struct {
Debug bool Debug bool
EbsOptimized bool EbsOptimized bool
ExpectedRootDevice string ExpectedRootDevice string
InstanceType string
IamInstanceProfile string IamInstanceProfile string
InstanceInitiatedShutdownBehavior string
InstanceType string
SourceAMI string SourceAMI string
SpotPrice string SpotPrice string
SpotPriceProduct string SpotPriceProduct string
@ -32,7 +32,6 @@ type StepRunSourceInstance struct {
Tags map[string]string Tags map[string]string
UserData string UserData string
UserDataFile string UserDataFile string
InstanceInitiatedShutdownBehavior string
instanceId string instanceId string
spotRequest *ec2.SpotInstanceRequest spotRequest *ec2.SpotInstanceRequest
@ -41,28 +40,9 @@ type StepRunSourceInstance struct {
func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepAction { func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2) ec2conn := state.Get("ec2").(*ec2.EC2)
keyName := state.Get("keyPair").(string) keyName := state.Get("keyPair").(string)
tempSecurityGroupIds := state.Get("securityGroupIds").([]string) securityGroupIds := aws.StringSlice(state.Get("securityGroupIds").([]string))
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
securityGroupIds := make([]*string, len(tempSecurityGroupIds))
for i, sg := range tempSecurityGroupIds {
log.Printf("[DEBUG] Waiting for tempSecurityGroup: %s", sg)
err := WaitUntilSecurityGroupExists(ec2conn,
&ec2.DescribeSecurityGroupsInput{
GroupIds: []*string{aws.String(sg)},
},
)
if err == nil {
log.Printf("[DEBUG] Found security group %s", sg)
securityGroupIds[i] = aws.String(sg)
} else {
err := fmt.Errorf("Timed out waiting for security group %s: %s", sg, err)
log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
}
userData := s.UserData userData := s.UserData
if s.UserDataFile != "" { if s.UserDataFile != "" {
contents, err := ioutil.ReadFile(s.UserDataFile) contents, err := ioutil.ReadFile(s.UserDataFile)
@ -368,38 +348,3 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
WaitForState(&stateChange) WaitForState(&stateChange)
} }
} }
func WaitUntilSecurityGroupExists(c *ec2.EC2, input *ec2.DescribeSecurityGroupsInput) error {
waiterCfg := waiter.Config{
Operation: "DescribeSecurityGroups",
Delay: 15,
MaxAttempts: 40,
Acceptors: []waiter.WaitAcceptor{
{
State: "success",
Matcher: "path",
Argument: "length(SecurityGroups[]) > `0`",
Expected: true,
},
{
State: "retry",
Matcher: "error",
Argument: "",
Expected: "InvalidGroup.NotFound",
},
{
State: "retry",
Matcher: "error",
Argument: "",
Expected: "InvalidSecurityGroupID.NotFound",
},
},
}
w := waiter.Waiter{
Client: c,
Input: input,
Config: waiterCfg,
}
return w.Wait()
}

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/private/waiter"
"github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/ec2"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/mitchellh/packer/common/uuid" "github.com/mitchellh/packer/common/uuid"
@ -26,6 +27,17 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
if len(s.SecurityGroupIds) > 0 { if len(s.SecurityGroupIds) > 0 {
_, err := ec2conn.DescribeSecurityGroups(
&ec2.DescribeSecurityGroupsInput{
GroupIds: aws.StringSlice(s.SecurityGroupIds),
},
)
if err != nil {
err := fmt.Errorf("Couldn't find specified security group: %s", err)
log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
log.Printf("Using specified security groups: %v", s.SecurityGroupIds) log.Printf("Using specified security groups: %v", s.SecurityGroupIds)
state.Put("securityGroupIds", s.SecurityGroupIds) state.Put("securityGroupIds", s.SecurityGroupIds)
return multistep.ActionContinue return multistep.ActionContinue
@ -87,6 +99,21 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt return multistep.ActionHalt
} }
log.Printf("[DEBUG] Waiting for temporary security group: %s", s.createdGroupId)
err = waitUntilSecurityGroupExists(ec2conn,
&ec2.DescribeSecurityGroupsInput{
GroupIds: []*string{aws.String(s.createdGroupId)},
},
)
if err == nil {
log.Printf("[DEBUG] Found security group %s", s.createdGroupId)
} else {
err := fmt.Errorf("Timed out waiting for security group %s: %s", s.createdGroupId, err)
log.Printf("[DEBUG] %s", err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
// Set some state data for use in future steps // Set some state data for use in future steps
state.Put("securityGroupIds", []string{s.createdGroupId}) state.Put("securityGroupIds", []string{s.createdGroupId})
@ -119,3 +146,38 @@ func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) {
"Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId)) "Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId))
} }
} }
func waitUntilSecurityGroupExists(c *ec2.EC2, input *ec2.DescribeSecurityGroupsInput) error {
waiterCfg := waiter.Config{
Operation: "DescribeSecurityGroups",
Delay: 15,
MaxAttempts: 40,
Acceptors: []waiter.WaitAcceptor{
{
State: "success",
Matcher: "path",
Argument: "length(SecurityGroups[]) > `0`",
Expected: true,
},
{
State: "retry",
Matcher: "error",
Argument: "",
Expected: "InvalidGroup.NotFound",
},
{
State: "retry",
Matcher: "error",
Argument: "",
Expected: "InvalidSecurityGroupID.NotFound",
},
},
}
w := waiter.Waiter{
Client: c,
Input: input,
Config: waiterCfg,
}
return w.Wait()
}