github.com/rothwerx/packer@v0.9.0/builder/amazon/common/step_security_group.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/ec2"
    10  	"github.com/mitchellh/multistep"
    11  	"github.com/mitchellh/packer/common/uuid"
    12  	"github.com/mitchellh/packer/helper/communicator"
    13  	"github.com/mitchellh/packer/packer"
    14  )
    15  
    16  type StepSecurityGroup struct {
    17  	CommConfig       *communicator.Config
    18  	SecurityGroupIds []string
    19  	VpcId            string
    20  
    21  	createdGroupId string
    22  }
    23  
    24  func (s *StepSecurityGroup) Run(state multistep.StateBag) multistep.StepAction {
    25  	ec2conn := state.Get("ec2").(*ec2.EC2)
    26  	ui := state.Get("ui").(packer.Ui)
    27  
    28  	if len(s.SecurityGroupIds) > 0 {
    29  		log.Printf("Using specified security groups: %v", s.SecurityGroupIds)
    30  		state.Put("securityGroupIds", s.SecurityGroupIds)
    31  		return multistep.ActionContinue
    32  	}
    33  
    34  	port := s.CommConfig.Port()
    35  	if port == 0 {
    36  		panic("port must be set to a non-zero value.")
    37  	}
    38  
    39  	// Create the group
    40  	ui.Say("Creating temporary security group for this instance...")
    41  	groupName := fmt.Sprintf("packer %s", uuid.TimeOrderedUUID())
    42  	log.Printf("Temporary group name: %s", groupName)
    43  	group := &ec2.CreateSecurityGroupInput{
    44  		GroupName:   &groupName,
    45  		Description: aws.String("Temporary group for Packer"),
    46  		VpcId:       &s.VpcId,
    47  	}
    48  	groupResp, err := ec2conn.CreateSecurityGroup(group)
    49  	if err != nil {
    50  		ui.Error(err.Error())
    51  		state.Put("error", err)
    52  		return multistep.ActionHalt
    53  	}
    54  
    55  	// Set the group ID so we can delete it later
    56  	s.createdGroupId = *groupResp.GroupId
    57  
    58  	// Authorize the SSH access for the security group
    59  	req := &ec2.AuthorizeSecurityGroupIngressInput{
    60  		GroupId:    groupResp.GroupId,
    61  		IpProtocol: aws.String("tcp"),
    62  		FromPort:   aws.Int64(int64(port)),
    63  		ToPort:     aws.Int64(int64(port)),
    64  		CidrIp:     aws.String("0.0.0.0/0"),
    65  	}
    66  
    67  	// We loop and retry this a few times because sometimes the security
    68  	// group isn't available immediately because AWS resources are eventaully
    69  	// consistent.
    70  	ui.Say(fmt.Sprintf(
    71  		"Authorizing access to port %d the temporary security group...",
    72  		port))
    73  	for i := 0; i < 5; i++ {
    74  		_, err = ec2conn.AuthorizeSecurityGroupIngress(req)
    75  		if err == nil {
    76  			break
    77  		}
    78  
    79  		log.Printf("Error authorizing. Will sleep and retry. %s", err)
    80  		time.Sleep((time.Duration(i) * time.Second) + 1)
    81  	}
    82  
    83  	if err != nil {
    84  		err := fmt.Errorf("Error creating temporary security group: %s", err)
    85  		state.Put("error", err)
    86  		ui.Error(err.Error())
    87  		return multistep.ActionHalt
    88  	}
    89  
    90  	// Set some state data for use in future steps
    91  	state.Put("securityGroupIds", []string{s.createdGroupId})
    92  
    93  	return multistep.ActionContinue
    94  }
    95  
    96  func (s *StepSecurityGroup) Cleanup(state multistep.StateBag) {
    97  	if s.createdGroupId == "" {
    98  		return
    99  	}
   100  
   101  	ec2conn := state.Get("ec2").(*ec2.EC2)
   102  	ui := state.Get("ui").(packer.Ui)
   103  
   104  	ui.Say("Deleting temporary security group...")
   105  
   106  	var err error
   107  	for i := 0; i < 5; i++ {
   108  		_, err = ec2conn.DeleteSecurityGroup(&ec2.DeleteSecurityGroupInput{GroupId: &s.createdGroupId})
   109  		if err == nil {
   110  			break
   111  		}
   112  
   113  		log.Printf("Error deleting security group: %s", err)
   114  		time.Sleep(5 * time.Second)
   115  	}
   116  
   117  	if err != nil {
   118  		ui.Error(fmt.Sprintf(
   119  			"Error cleaning up security group. Please delete the group manually: %s", s.createdGroupId))
   120  	}
   121  }