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 }