func (e *EC2) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { imageID, err := common.GetMatchingImageID(e, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(e, &instance.Flavor) if err != nil { return nil, err } region := DEFAULT_REGION if instance.Region != "" { region = instance.Region } svc := e.getService(region) opts := ec2.RunInstancesInput{ ImageId: aws.String(imageID), InstanceType: aws.String(flavorID), MinCount: aws.Int64(1), MaxCount: aws.Int64(1), } password := instance.Password if password == "" { password = utils.Uid(16) } userData := "#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n" opts.UserData = aws.String(base64.StdEncoding.EncodeToString([]byte(userData))) if instance.Flavor.DiskGB > 0 { opts.BlockDeviceMappings = []*ec2.BlockDeviceMapping{ { Ebs: &ec2.EbsBlockDevice{ VolumeSize: aws.Int64(int64(instance.Flavor.DiskGB)), DeleteOnTermination: aws.Bool(true), VolumeType: aws.String("gp2"), }, }, } } if len(instance.PublicKey.Key) > 0 { keyName := utils.Uid(8) _, err := svc.ImportKeyPair(&ec2.ImportKeyPairInput{ KeyName: aws.String(keyName), PublicKeyMaterial: instance.PublicKey.Key, }) if err != nil { return nil, fmt.Errorf("failed to import public key: %v", err) } defer svc.DeleteKeyPair(&ec2.DeleteKeyPairInput{ KeyName: aws.String(keyName), }) opts.KeyName = aws.String(keyName) } res, err := svc.RunInstances(&opts) if err != nil { return nil, err } else if len(res.Instances) != 1 { return nil, fmt.Errorf("attempted to provision a single instance, but reservation contains %d instances", len(res.Instances)) } resInstance := res.Instances[0] return &compute.Instance{ ID: encodeID(String(resInstance.InstanceId), region), Status: e.mapInstanceStatus(String(resInstance.State.Name)), Password: password, }, nil }