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"
"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/mitchellh/multistep"
@ -23,8 +22,9 @@ type StepRunSourceInstance struct {
Debug bool
EbsOptimized bool
ExpectedRootDevice string
InstanceType string
IamInstanceProfile string
InstanceInitiatedShutdownBehavior string
InstanceType string
SourceAMI string
SpotPrice string
SpotPriceProduct string
@ -32,7 +32,6 @@ type StepRunSourceInstance struct {
Tags map[string]string
UserData string
UserDataFile string
InstanceInitiatedShutdownBehavior string
instanceId string
spotRequest *ec2.SpotInstanceRequest
@ -41,28 +40,9 @@ type StepRunSourceInstance struct {
func (s *StepRunSourceInstance) Run(state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2)
keyName := state.Get("keyPair").(string)
tempSecurityGroupIds := state.Get("securityGroupIds").([]string)
securityGroupIds := aws.StringSlice(state.Get("securityGroupIds").([]string))
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
if s.UserDataFile != "" {
contents, err := ioutil.ReadFile(s.UserDataFile)
@ -368,38 +348,3 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
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"
"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/mitchellh/multistep"
"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)
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)
state.Put("securityGroupIds", s.SecurityGroupIds)
return multistep.ActionContinue
@ -87,6 +99,21 @@ func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
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
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))
}
}
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()
}