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