// createAMIs actually creates the AMI(s) func createAMIs(awsec2 *ec2.EC2, instances []ec2.Instance, s *session) map[string]string { newAMIs := make(map[string]string) pendingAMIs := make(map[string]bool) for _, instance := range instances { backupAmiName := fmt.Sprintf("%s-%s-%s", s.instanceNameTag, timeStamp, instance.InstanceId) backupDesc := fmt.Sprintf("%s %s %s", s.instanceNameTag, timeString, instance.InstanceId) blockDevices := []ec2.BlockDeviceMapping{} for _, i := range s.ignoreVolumes { blockDevices = append(blockDevices, ec2.BlockDeviceMapping{DeviceName: i, NoDevice: true}) } createOpts := ec2.CreateImage{ InstanceId: instance.InstanceId, Name: backupAmiName, Description: backupDesc, NoReboot: true, BlockDevices: blockDevices, } resp, err := awsec2.CreateImage(&createOpts) if err != nil { s.fatal(fmt.Sprintf("Error creating new AMI: %s", err.Error())) } _, err = awsec2.CreateTags([]string{resp.ImageId}, []ec2.Tag{ {"hostname", s.instanceNameTag}, {"instance", instance.InstanceId}, {"date", timeString}, {"timestamp", timeSecs}, }) if err != nil { s.fatal(fmt.Sprintf("Error tagging new AMI: %s", err.Error())) } newAMIs[resp.ImageId] = instance.InstanceId pendingAMIs[resp.ImageId] = true s.debug(fmt.Sprintf("Creating new AMI %s for %s (%s)", resp.ImageId, s.instanceNameTag, instance.InstanceId)) } // wait for AMIs to be ready done := make(chan bool) go func() { for len(pendingAMIs) > 0 { s.debug(fmt.Sprintf("Sleeping for %d pending AMIs", len(pendingAMIs))) time.Sleep(apiPollInterval) list := []string{} for k, _ := range pendingAMIs { list = append(list, k) } images, err := awsec2.Images(list, nil) if err != nil { s.fatal("EC2 API Images failed") } for _, image := range images.Images { if image.State == "available" { delete(pendingAMIs, image.Id) s.ok(fmt.Sprintf("Created new AMI %s", image.Id)) } } } done <- true }() select { case <-done: case <-time.After(s.timeout): list := []string{} for k, _ := range pendingAMIs { list = append(list, k) } s.fatal(fmt.Sprintf("Timeout waiting for AMIs in region %s: %s", s.sourceRegion.Name, strings.Join(list, " ,"))) } return newAMIs }