mirror of
https://github.com/hashicorp/packer.git
synced 2026-10-12 17:22:01 -04:00
This commit moves the Amazon builders of Packer away from the Hashicorp fork of the goamz library to the official AWS SDK for Go, in order that third party plugins may depend on the more complete official library more easily.
117 lines
3.0 KiB
Go
117 lines
3.0 KiB
Go
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/awslabs/aws-sdk-go/aws"
|
|
"github.com/awslabs/aws-sdk-go/service/ec2"
|
|
"github.com/mitchellh/multistep"
|
|
"github.com/mitchellh/packer/common/uuid"
|
|
"github.com/mitchellh/packer/packer"
|
|
)
|
|
|
|
type StepSecurityGroup struct {
|
|
SecurityGroupIds []string
|
|
SSHPort int
|
|
VpcId string
|
|
|
|
createdGroupId string
|
|
}
|
|
|
|
func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
|
|
ec2conn := state.Get("ec2").(*ec2.EC2)
|
|
ui := state.Get("ui").(packer.Ui)
|
|
|
|
if len(s.SecurityGroupIds) > 0 {
|
|
log.Printf("Using specified security groups: %v", s.SecurityGroupIds)
|
|
state.Put("securityGroupIds", s.SecurityGroupIds)
|
|
return multistep.ActionContinue
|
|
}
|
|
|
|
if s.SSHPort == 0 {
|
|
panic("SSHPort must be set to a non-zero value.")
|
|
}
|
|
|
|
// Create the group
|
|
ui.Say("Creating temporary security group for this instance...")
|
|
groupName := fmt.Sprintf("packer %s", uuid.TimeOrderedUUID())
|
|
log.Printf("Temporary group name: %s", groupName)
|
|
group := &ec2.CreateSecurityGroupInput{
|
|
GroupName: &groupName,
|
|
Description: aws.String("Temporary group for Packer"),
|
|
VPCID: &s.VpcId,
|
|
}
|
|
groupResp, err := ec2conn.CreateSecurityGroup(group)
|
|
if err != nil {
|
|
ui.Error(err.Error())
|
|
return multistep.ActionHalt
|
|
}
|
|
|
|
// Set the group ID so we can delete it later
|
|
s.createdGroupId = *groupResp.GroupID
|
|
|
|
// Authorize the SSH access for the security group
|
|
req := &ec2.AuthorizeSecurityGroupIngressInput{
|
|
GroupID: groupResp.GroupID,
|
|
IPProtocol: aws.String("tcp"),
|
|
FromPort: aws.Long(int64(s.SSHPort)),
|
|
ToPort: aws.Long(int64(s.SSHPort)),
|
|
CIDRIP: aws.String("0.0.0.0/0"),
|
|
}
|
|
|
|
// We loop and retry this a few times because sometimes the security
|
|
// group isn't available immediately because AWS resources are eventaully
|
|
// consistent.
|
|
ui.Say("Authorizing SSH access on the temporary security group...")
|
|
for i := 0; i < 5; i++ {
|
|
_, err = ec2conn.AuthorizeSecurityGroupIngress(req)
|
|
if err == nil {
|
|
break
|
|
}
|
|
|
|
log.Printf("Error authorizing. Will sleep and retry. %s", err)
|
|
time.Sleep((time.Duration(i) * time.Second) + 1)
|
|
}
|
|
|
|
if err != nil {
|
|
err := fmt.Errorf("Error creating temporary security group: %s", err)
|
|
state.Put("error", err)
|
|
ui.Error(err.Error())
|
|
return multistep.ActionHalt
|
|
}
|
|
|
|
// Set some state data for use in future steps
|
|
state.Put("securityGroupIds", []string{s.createdGroupId})
|
|
|
|
return multistep.ActionContinue
|
|
}
|
|
|
|
func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) {
|
|
if s.createdGroupId == "" {
|
|
return
|
|
}
|
|
|
|
ec2conn := state.Get("ec2").(*ec2.EC2)
|
|
ui := state.Get("ui").(packer.Ui)
|
|
|
|
ui.Say("Deleting temporary security group...")
|
|
|
|
var err error
|
|
for i := 0; i < 5; i++ {
|
|
_, err = ec2conn.DeleteSecurityGroup(&ec2.DeleteSecurityGroupInput{GroupID: &s.createdGroupId})
|
|
if err == nil {
|
|
break
|
|
}
|
|
|
|
log.Printf("Error deleting security group: %s", err)
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
|
|
if err != nil {
|
|
ui.Error(fmt.Sprintf(
|
|
"Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId))
|
|
}
|
|
}
|