Merge pull request #4243 from rickard-von-essen/aws-snapshot-users-groups
WIP: amazon: Add snapshot_users and snapshot_groups
This commit is contained in:
commit
56f2bfa5ff
|
@ -261,6 +261,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
Users: b.config.AMIUsers,
|
||||
Groups: b.config.AMIGroups,
|
||||
ProductCodes: b.config.AMIProductCodes,
|
||||
SnapshotUsers: b.config.SnapshotUsers,
|
||||
SnapshotGroups: b.config.SnapshotGroups,
|
||||
},
|
||||
&awscommon.StepCreateTags{
|
||||
Tags: b.config.AMITags,
|
||||
|
|
|
@ -23,6 +23,8 @@ type AMIConfig struct {
|
|||
AMIEncryptBootVolume bool `mapstructure:"encrypt_boot"`
|
||||
AMIKmsKeyId string `mapstructure:"kms_key_id"`
|
||||
SnapshotTags map[string]string `mapstructure:"snapshot_tags"`
|
||||
SnapshotUsers []string `mapstructure:"snapshot_users"`
|
||||
SnapshotGroups []string `mapstructure:"snapshot_groups"`
|
||||
}
|
||||
|
||||
func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
|
@ -62,6 +64,10 @@ func (c *AMIConfig) Prepare(ctx *interpolate.Context) []error {
|
|||
errs = append(errs, fmt.Errorf("Cannot share AMI with encrypted boot volume"))
|
||||
}
|
||||
|
||||
if len(c.SnapshotUsers) > 0 && len(c.AMIKmsKeyId) == 0 && c.AMIEncryptBootVolume {
|
||||
errs = append(errs, fmt.Errorf("Cannot share snapshot encrypted with default KMS key"))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction {
|
|||
ec2conn := state.Get("ec2").(*ec2.EC2)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
amis := state.Get("amis").(map[string]string)
|
||||
snapshots := state.Get("snapshots").(map[string][]string)
|
||||
ami := amis[*ec2conn.Config.Region]
|
||||
|
||||
if len(s.Regions) == 0 {
|
||||
|
@ -46,11 +47,12 @@ func (s *StepAMIRegionCopy) Run(state multistep.StateBag) multistep.StepAction {
|
|||
|
||||
go func(region string) {
|
||||
defer wg.Done()
|
||||
id, err := amiRegionCopy(state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region)
|
||||
id, snapshotIds, err := amiRegionCopy(state, s.AccessConfig, s.Name, ami, region, *ec2conn.Config.Region)
|
||||
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
amis[region] = id
|
||||
snapshots[region] = snapshotIds
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
|
@ -77,20 +79,21 @@ func (s *StepAMIRegionCopy) Cleanup(state multistep.StateBag) {
|
|||
}
|
||||
|
||||
// amiRegionCopy does a copy for the given AMI to the target region and
|
||||
// returns the resulting ID or error.
|
||||
// returns the resulting ID and snapshot IDs, or error.
|
||||
func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string, imageId string,
|
||||
target string, source string) (string, error) {
|
||||
target string, source string) (string, []string, error) {
|
||||
snapshotIds := []string{}
|
||||
|
||||
// Connect to the region where the AMI will be copied to
|
||||
awsConfig, err := config.Config()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", snapshotIds, err
|
||||
}
|
||||
awsConfig.Region = aws.String(target)
|
||||
|
||||
session, err := session.NewSession(awsConfig)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", snapshotIds, err
|
||||
}
|
||||
regionconn := ec2.New(session)
|
||||
|
||||
|
@ -101,7 +104,7 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string,
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error Copying AMI (%s) to region (%s): %s",
|
||||
return "", snapshotIds, fmt.Errorf("Error Copying AMI (%s) to region (%s): %s",
|
||||
imageId, target, err)
|
||||
}
|
||||
|
||||
|
@ -113,9 +116,22 @@ func amiRegionCopy(state multistep.StateBag, config *AccessConfig, name string,
|
|||
}
|
||||
|
||||
if _, err := WaitForState(&stateChange); err != nil {
|
||||
return "", fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s",
|
||||
return "", snapshotIds, fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s",
|
||||
*resp.ImageId, target, err)
|
||||
}
|
||||
|
||||
return *resp.ImageId, nil
|
||||
// Getting snapshot IDs out of the copied AMI
|
||||
describeImageResp, err := regionconn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{resp.ImageId}})
|
||||
if err != nil {
|
||||
return "", snapshotIds, fmt.Errorf("Error describing copied AMI (%s) in region (%s): %s",
|
||||
imageId, target, err)
|
||||
}
|
||||
|
||||
for _, blockDeviceMapping := range describeImageResp.Images[0].BlockDeviceMappings {
|
||||
if blockDeviceMapping.Ebs != nil {
|
||||
snapshotIds = append(snapshotIds, *blockDeviceMapping.Ebs.SnapshotId)
|
||||
}
|
||||
}
|
||||
|
||||
return *resp.ImageId, snapshotIds, nil
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import (
|
|||
type StepModifyAMIAttributes struct {
|
||||
Users []string
|
||||
Groups []string
|
||||
SnapshotUsers []string
|
||||
SnapshotGroups []string
|
||||
ProductCodes []string
|
||||
Description string
|
||||
}
|
||||
|
@ -21,6 +23,7 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
|
|||
ec2conn := state.Get("ec2").(*ec2.EC2)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
amis := state.Get("amis").(map[string]string)
|
||||
snapshots := state.Get("snapshots").(map[string][]string)
|
||||
|
||||
// Determine if there is any work to do.
|
||||
valid := false
|
||||
|
@ -28,51 +31,89 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
|
|||
valid = valid || (s.Users != nil && len(s.Users) > 0)
|
||||
valid = valid || (s.Groups != nil && len(s.Groups) > 0)
|
||||
valid = valid || (s.ProductCodes != nil && len(s.ProductCodes) > 0)
|
||||
valid = valid || (s.SnapshotUsers != nil && len(s.SnapshotUsers) > 0)
|
||||
valid = valid || (s.SnapshotGroups != nil && len(s.SnapshotGroups) > 0)
|
||||
|
||||
if !valid {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
// Construct the modify image attribute requests we're going to make.
|
||||
// We need to make each separately since the EC2 API only allows changing
|
||||
// one type at a kind currently.
|
||||
// Construct the modify image and snapshot attribute requests we're going
|
||||
// to make. We need to make each separately since the EC2 API only allows
|
||||
// changing one type at a kind currently.
|
||||
options := make(map[string]*ec2.ModifyImageAttributeInput)
|
||||
if s.Description != "" {
|
||||
options["description"] = &ec2.ModifyImageAttributeInput{
|
||||
Description: &ec2.AttributeValue{Value: &s.Description},
|
||||
}
|
||||
}
|
||||
snapshotOptions := make(map[string]*ec2.ModifySnapshotAttributeInput)
|
||||
|
||||
if len(s.Groups) > 0 {
|
||||
groups := make([]*string, len(s.Groups))
|
||||
adds := make([]*ec2.LaunchPermission, len(s.Groups))
|
||||
addsImage := make([]*ec2.LaunchPermission, len(s.Groups))
|
||||
addGroups := &ec2.ModifyImageAttributeInput{
|
||||
LaunchPermission: &ec2.LaunchPermissionModifications{},
|
||||
}
|
||||
|
||||
for i, g := range s.Groups {
|
||||
groups[i] = aws.String(g)
|
||||
adds[i] = &ec2.LaunchPermission{
|
||||
addsImage[i] = &ec2.LaunchPermission{
|
||||
Group: aws.String(g),
|
||||
}
|
||||
}
|
||||
addGroups.UserGroups = groups
|
||||
addGroups.LaunchPermission.Add = adds
|
||||
|
||||
addGroups.UserGroups = groups
|
||||
addGroups.LaunchPermission.Add = addsImage
|
||||
options["groups"] = addGroups
|
||||
}
|
||||
|
||||
if len(s.SnapshotGroups) > 0 {
|
||||
groups := make([]*string, len(s.SnapshotGroups))
|
||||
addsSnapshot := make([]*ec2.CreateVolumePermission, len(s.SnapshotGroups))
|
||||
addSnapshotGroups := &ec2.ModifySnapshotAttributeInput{
|
||||
CreateVolumePermission: &ec2.CreateVolumePermissionModifications{},
|
||||
}
|
||||
|
||||
for i, g := range s.SnapshotGroups {
|
||||
groups[i] = aws.String(g)
|
||||
addsSnapshot[i] = &ec2.CreateVolumePermission{
|
||||
Group: aws.String(g),
|
||||
}
|
||||
}
|
||||
addSnapshotGroups.GroupNames = groups
|
||||
addSnapshotGroups.CreateVolumePermission.Add = addsSnapshot
|
||||
snapshotOptions["groups"] = addSnapshotGroups
|
||||
}
|
||||
|
||||
if len(s.Users) > 0 {
|
||||
users := make([]*string, len(s.Users))
|
||||
adds := make([]*ec2.LaunchPermission, len(s.Users))
|
||||
addsImage := make([]*ec2.LaunchPermission, len(s.Users))
|
||||
for i, u := range s.Users {
|
||||
users[i] = aws.String(u)
|
||||
adds[i] = &ec2.LaunchPermission{UserId: aws.String(u)}
|
||||
addsImage[i] = &ec2.LaunchPermission{UserId: aws.String(u)}
|
||||
}
|
||||
|
||||
options["users"] = &ec2.ModifyImageAttributeInput{
|
||||
UserIds: users,
|
||||
LaunchPermission: &ec2.LaunchPermissionModifications{
|
||||
Add: adds,
|
||||
Add: addsImage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if len(s.SnapshotUsers) > 0 {
|
||||
users := make([]*string, len(s.SnapshotUsers))
|
||||
addsSnapshot := make([]*ec2.CreateVolumePermission, len(s.SnapshotUsers))
|
||||
for i, u := range s.SnapshotUsers {
|
||||
users[i] = aws.String(u)
|
||||
addsSnapshot[i] = &ec2.CreateVolumePermission{UserId: aws.String(u)}
|
||||
}
|
||||
|
||||
snapshotOptions["users"] = &ec2.ModifySnapshotAttributeInput{
|
||||
UserIds: users,
|
||||
CreateVolumePermission: &ec2.CreateVolumePermissionModifications{
|
||||
Add: addsSnapshot,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +128,7 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
|
|||
}
|
||||
}
|
||||
|
||||
// Modifying image attributes
|
||||
for region, ami := range amis {
|
||||
ui.Say(fmt.Sprintf("Modifying attributes on AMI (%s)...", ami))
|
||||
awsConfig := aws.Config{
|
||||
|
@ -114,6 +156,30 @@ func (s *StepModifyAMIAttributes) Run(state multistep.StateBag) multistep.StepAc
|
|||
}
|
||||
}
|
||||
|
||||
// Modifying snapshot attributes
|
||||
for region, region_snapshots := range snapshots {
|
||||
for _, snapshot := range region_snapshots {
|
||||
ui.Say(fmt.Sprintf("Modifying attributes on snapshot (%s)...", snapshot))
|
||||
awsConfig := aws.Config{
|
||||
Credentials: ec2conn.Config.Credentials,
|
||||
Region: aws.String(region),
|
||||
}
|
||||
session := session.New(&awsConfig)
|
||||
regionconn := ec2.New(session)
|
||||
for name, input := range snapshotOptions {
|
||||
ui.Message(fmt.Sprintf("Modifying: %s", name))
|
||||
input.SnapshotId = &snapshot
|
||||
_, err := regionconn.ModifySnapshotAttribute(input)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error modify snapshot attributes: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
Users: b.config.AMIUsers,
|
||||
Groups: b.config.AMIGroups,
|
||||
ProductCodes: b.config.AMIProductCodes,
|
||||
SnapshotUsers: b.config.SnapshotUsers,
|
||||
SnapshotGroups: b.config.SnapshotGroups,
|
||||
},
|
||||
&awscommon.StepCreateTags{
|
||||
Tags: b.config.AMITags,
|
||||
|
|
|
@ -66,6 +66,14 @@ func (s *stepCreateAMI) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
s.image = imagesResp.Images[0]
|
||||
|
||||
snapshots := make(map[string][]string)
|
||||
for _, blockDeviceMapping := range imagesResp.Images[0].BlockDeviceMappings {
|
||||
if blockDeviceMapping.Ebs != nil {
|
||||
snapshots[*ec2conn.Config.Region] = append(snapshots[*ec2conn.Config.Region], *blockDeviceMapping.Ebs.SnapshotId)
|
||||
}
|
||||
}
|
||||
state.Put("snapshots", snapshots)
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,22 @@ func (s *stepCreateEncryptedAMICopy) Run(state multistep.StateBag) multistep.Ste
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
// Get the encrypted AMI image, we need the new snapshot id's
|
||||
encImagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{aws.String(*copyResp.ImageId)}})
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error searching for AMI: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
encImage := encImagesResp.Images[0]
|
||||
var encSnapshots []string
|
||||
for _, blockDevice := range encImage.BlockDeviceMappings {
|
||||
if blockDevice.Ebs != nil && blockDevice.Ebs.SnapshotId != nil {
|
||||
encSnapshots = append(encSnapshots, *blockDevice.Ebs.SnapshotId)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the unencrypted AMI image
|
||||
unencImagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{aws.String(id)}})
|
||||
if err != nil {
|
||||
|
@ -97,10 +113,10 @@ func (s *stepCreateEncryptedAMICopy) Run(state multistep.StateBag) multistep.Ste
|
|||
|
||||
// Remove associated unencrypted snapshot(s)
|
||||
ui.Say("Deleting unencrypted snapshots")
|
||||
snapshots := state.Get("snapshots").(map[string][]string)
|
||||
|
||||
for _, blockDevice := range unencImage.BlockDeviceMappings {
|
||||
if blockDevice.Ebs != nil {
|
||||
if blockDevice.Ebs.SnapshotId != nil {
|
||||
if blockDevice.Ebs != nil && blockDevice.Ebs.SnapshotId != nil {
|
||||
ui.Message(fmt.Sprintf("Snapshot ID: %s", *blockDevice.Ebs.SnapshotId))
|
||||
deleteSnapOpts := &ec2.DeleteSnapshotInput{
|
||||
SnapshotId: aws.String(*blockDevice.Ebs.SnapshotId),
|
||||
|
@ -111,11 +127,12 @@ func (s *stepCreateEncryptedAMICopy) Run(state multistep.StateBag) multistep.Ste
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace original AMI ID with Encrypted ID in state
|
||||
amis[region] = *copyResp.ImageId
|
||||
snapshots[region] = encSnapshots
|
||||
state.Put("amis", amis)
|
||||
state.Put("snapshots", snapshots)
|
||||
|
||||
imagesResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{copyResp.ImageId}})
|
||||
if err != nil {
|
||||
|
|
|
@ -263,6 +263,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
Users: b.config.AMIUsers,
|
||||
Groups: b.config.AMIGroups,
|
||||
ProductCodes: b.config.AMIProductCodes,
|
||||
SnapshotUsers: b.config.SnapshotUsers,
|
||||
SnapshotGroups: b.config.SnapshotGroups,
|
||||
},
|
||||
&awscommon.StepCreateTags{
|
||||
Tags: b.config.AMITags,
|
||||
|
|
|
@ -207,6 +207,17 @@ each category, the available configuration keys are alphabetized.
|
|||
- `skip_region_validation` (boolean) - Set to true if you want to skip
|
||||
validation of the `ami_regions` configuration option. Default `false`.
|
||||
|
||||
- `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot.
|
||||
They will override AMI tags if already applied to snapshot.
|
||||
|
||||
- `snapshot_groups` (array of strings) - A list of groups that have access to
|
||||
create volumes from the snapshot(s). By default no groups have permission to create
|
||||
volumes form the snapshot(s). `all` will make the snapshot publicly accessible.
|
||||
|
||||
- `snapshot_users` (array of strings) - A list of account IDs that have access to
|
||||
create volumes from the snapshot(s). By default no additional users other than the
|
||||
user creating the AMI has permissions to create volumes from the backing snapshot(s).
|
||||
|
||||
- `source_ami_filter` (object) - Filters used to populate the `source_ami` field.
|
||||
Example:
|
||||
|
||||
|
@ -237,9 +248,6 @@ each category, the available configuration keys are alphabetized.
|
|||
- `most_recent` (bool) - Selects the newest created image when true.
|
||||
This is most useful for selecting a daily distro build.
|
||||
|
||||
- `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot.
|
||||
They will override AMI tags if already applied to snapshot.
|
||||
|
||||
- `tags` (object of key/value strings) - Tags applied to the AMI.
|
||||
|
||||
## Basic Example
|
||||
|
|
|
@ -114,9 +114,21 @@ builder.
|
|||
described above. Note that if this is specified, you must omit the
|
||||
`security_group_id`.
|
||||
|
||||
- `shutdown_behaviour` (string) - Automatically terminate instances on shutdown
|
||||
incase packer exits ungracefully. Possible values are "stop" and "terminate",
|
||||
default is stop.
|
||||
|
||||
- `skip_region_validation` (boolean) - Set to true if you want to skip
|
||||
validation of the region configuration option. Defaults to false.
|
||||
|
||||
- `snapshot_groups` (array of strings) - A list of groups that have access to
|
||||
create volumes from the snapshot(s). By default no groups have permission to create
|
||||
volumes form the snapshot(s). `all` will make the snapshot publicly accessible.
|
||||
|
||||
- `snapshot_users` (array of strings) - A list of account IDs that have access to
|
||||
create volumes from the snapshot(s). By default no additional users other than the
|
||||
user creating the AMI has permissions to create volumes from the backing snapshot(s).
|
||||
|
||||
- `source_ami_filter` (object) - Filters used to populate the `source_ami` field.
|
||||
Example:
|
||||
|
||||
|
@ -196,10 +208,6 @@ builder.
|
|||
- `windows_password_timeout` (string) - The timeout for waiting for a Windows
|
||||
password for Windows instances. Defaults to 20 minutes. Example value: "10m"
|
||||
|
||||
- `shutdown_behaviour` (string) - Automatically terminate instances on shutdown
|
||||
incase packer exits ungracefully. Possible values are "stop" and "terminate",
|
||||
default is stop.
|
||||
|
||||
## Basic Example
|
||||
|
||||
```
|
||||
|
|
|
@ -190,9 +190,24 @@ builder.
|
|||
described above. Note that if this is specified, you must omit the
|
||||
`security_group_id`.
|
||||
|
||||
- `shutdown_behaviour` (string) - Automatically terminate instances on shutdown
|
||||
incase packer exits ungracefully. Possible values are "stop" and "terminate",
|
||||
default is stop.
|
||||
|
||||
- `skip_region_validation` (boolean) - Set to true if you want to skip
|
||||
validation of the region configuration option. Default `false`.
|
||||
|
||||
- `snapshot_groups` (array of strings) - A list of groups that have access to
|
||||
create volumes from the snapshot(s). By default no groups have permission to create
|
||||
volumes form the snapshot(s). `all` will make the snapshot publicly accessible.
|
||||
|
||||
- `snapshot_users` (array of strings) - A list of account IDs that have access to
|
||||
create volumes from the snapshot(s). By default no additional users other than the
|
||||
user creating the AMI has permissions to create volumes from the backing snapshot(s).
|
||||
|
||||
- `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot.
|
||||
They will override AMI tags if already applied to snapshot.
|
||||
|
||||
- `source_ami_filter` (object) - Filters used to populate the `source_ami` field.
|
||||
Example:
|
||||
|
||||
|
@ -223,9 +238,6 @@ builder.
|
|||
- `most_recent` (bool) - Selects the newest created image when true.
|
||||
This is most useful for selecting a daily distro build.
|
||||
|
||||
- `snapshot_tags` (object of key/value strings) - Tags to apply to snapshot.
|
||||
They will override AMI tags if already applied to snapshot.
|
||||
|
||||
- `spot_price` (string) - The maximum hourly price to pay for a spot instance
|
||||
to create the AMI. Spot instances are a type of instance that EC2 starts
|
||||
when the current spot price is less than the maximum price you specify. Spot
|
||||
|
@ -287,10 +299,6 @@ builder.
|
|||
- `windows_password_timeout` (string) - The timeout for waiting for a Windows
|
||||
password for Windows instances. Defaults to 20 minutes. Example value: "10m"
|
||||
|
||||
- `shutdown_behaviour` (string) - Automatically terminate instances on shutdown
|
||||
incase packer exits ungracefully. Possible values are "stop" and "terminate",
|
||||
default is stop.
|
||||
|
||||
## Basic Example
|
||||
|
||||
Here is a basic example. You will need to provide access keys, and may need to change the AMI IDs according to what images exist at the time the template is run:
|
||||
|
|
|
@ -207,6 +207,14 @@ builder.
|
|||
- `skip_region_validation` (boolean) - Set to true if you want to skip
|
||||
validation of the region configuration option. Default `false`.
|
||||
|
||||
- `snapshot_groups` (array of strings) - A list of groups that have access to
|
||||
create volumes from the snapshot(s). By default no groups have permission to create
|
||||
volumes form the snapshot(s). `all` will make the snapshot publicly accessible.
|
||||
|
||||
- `snapshot_users` (array of strings) - A list of account IDs that have access to
|
||||
create volumes from the snapshot(s). By default no additional users other than the
|
||||
user creating the AMI has permissions to create volumes from the backing snapshot(s).
|
||||
|
||||
- `source_ami_filter` (object) - Filters used to populate the `source_ami` field.
|
||||
Example:
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ Packer to work:
|
|||
"ec2:GetPasswordData",
|
||||
"ec2:ModifyImageAttribute",
|
||||
"ec2:ModifyInstanceAttribute",
|
||||
"ec2:ModifySnapshotAttribute",
|
||||
"ec2:RegisterImage",
|
||||
"ec2:RunInstances",
|
||||
"ec2:StopInstances",
|
||||
|
|
Loading…
Reference in New Issue