Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_ami_launch_permission: support group permissions #20677

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/20677.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_ami_launch_permission: Add `group` support for making public AMIs
```
83 changes: 69 additions & 14 deletions aws/resource_aws_ami_launch_permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,32 @@ func resourceAwsAmiLaunchPermission() *schema.Resource {
Importer: &schema.ResourceImporter{
State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
idParts := strings.Split(d.Id(), "/")
if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" {
return nil, fmt.Errorf("Unexpected format of ID (%q), expected ACCOUNT-ID/IMAGE-ID", d.Id())

parseError := fmt.Errorf("Unexpected format of ID (%q), expected ACCOUNT-ID/IMAGE-ID or group/GROUP-NAME/ACCOUNT-ID", d.Id())
if len(idParts) == 2 {
// Parsing the ACCOUNT-ID/IMAGE-ID branch
if idParts[0] == "" || idParts[1] == "" {
return nil, parseError
}
accountId := idParts[0]
imageId := idParts[1]
d.Set("account_id", accountId)
d.Set("image_id", imageId)
d.SetId(fmt.Sprintf("%s-account-%s", imageId, accountId))
} else if len(idParts) == 3 && idParts[0] == "group" {
// Parsing the group/GROUP-NAME/ACCOUNT-ID branch
if idParts[1] == "" || idParts[2] == "" {
return nil, parseError
}
groupName := idParts[1]
imageId := idParts[2]
d.Set("group_name", groupName)
d.Set("image_id", imageId)
d.SetId(fmt.Sprintf("%s-group-%s", imageId, groupName))
} else {
return nil, parseError
}
accountId := idParts[0]
imageId := idParts[1]
d.Set("account_id", accountId)
d.Set("image_id", imageId)
d.SetId(fmt.Sprintf("%s-%s", imageId, accountId))

return []*schema.ResourceData{d}, nil
},
},
Expand All @@ -39,8 +57,21 @@ func resourceAwsAmiLaunchPermission() *schema.Resource {
},
"account_id": {
Type: schema.TypeString,
Required: true,
Optional: true,
ForceNew: true,
ExactlyOneOf: []string{
"account_id",
"group_name",
},
},
"group_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ExactlyOneOf: []string{
"account_id",
"group_name",
},
},
},
}
Expand All @@ -51,28 +82,42 @@ func resourceAwsAmiLaunchPermissionCreate(d *schema.ResourceData, meta interface

image_id := d.Get("image_id").(string)
account_id := d.Get("account_id").(string)
group_name := d.Get("group_name").(string)

var launch_permission *ec2.LaunchPermission

if account_id != "" {
launch_permission = &ec2.LaunchPermission{UserId: aws.String(account_id)}
} else {
launch_permission = &ec2.LaunchPermission{Group: aws.String(group_name)}
}

_, err := conn.ModifyImageAttribute(&ec2.ModifyImageAttributeInput{
ImageId: aws.String(image_id),
Attribute: aws.String(ec2.ImageAttributeNameLaunchPermission),
LaunchPermission: &ec2.LaunchPermissionModifications{
Add: []*ec2.LaunchPermission{
{UserId: aws.String(account_id)},
launch_permission,
},
},
})
if err != nil {
return fmt.Errorf("error creating AMI launch permission: %w", err)
}

d.SetId(fmt.Sprintf("%s-%s", image_id, account_id))
if account_id != "" {
d.SetId(fmt.Sprintf("%s-account-%s", image_id, account_id))
} else {
d.SetId(fmt.Sprintf("%s-group-%s", image_id, group_name))
}

return nil
}

func resourceAwsAmiLaunchPermissionRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn

exists, err := hasLaunchPermission(conn, d.Get("image_id").(string), d.Get("account_id").(string))
exists, err := hasLaunchPermission(conn, d.Get("image_id").(string), d.Get("account_id").(string), d.Get("group_name").(string))
if err != nil {
return fmt.Errorf("error reading AMI launch permission (%s): %w", d.Id(), err)
}
Expand All @@ -94,13 +139,21 @@ func resourceAwsAmiLaunchPermissionDelete(d *schema.ResourceData, meta interface

image_id := d.Get("image_id").(string)
account_id := d.Get("account_id").(string)
group_name := d.Get("group_name").(string)

var launch_permission *ec2.LaunchPermission

if account_id != "" {
launch_permission = &ec2.LaunchPermission{UserId: aws.String(account_id)}
} else {
launch_permission = &ec2.LaunchPermission{Group: aws.String(group_name)}
}
_, err := conn.ModifyImageAttribute(&ec2.ModifyImageAttributeInput{
ImageId: aws.String(image_id),
Attribute: aws.String(ec2.ImageAttributeNameLaunchPermission),
LaunchPermission: &ec2.LaunchPermissionModifications{
Remove: []*ec2.LaunchPermission{
{UserId: aws.String(account_id)},
launch_permission,
},
},
})
Expand All @@ -111,7 +164,7 @@ func resourceAwsAmiLaunchPermissionDelete(d *schema.ResourceData, meta interface
return nil
}

func hasLaunchPermission(conn *ec2.EC2, image_id string, account_id string) (bool, error) {
func hasLaunchPermission(conn *ec2.EC2, image_id string, account_id string, group_name string) (bool, error) {
attrs, err := conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{
ImageId: aws.String(image_id),
Attribute: aws.String(ec2.ImageAttributeNameLaunchPermission),
Expand All @@ -127,7 +180,9 @@ func hasLaunchPermission(conn *ec2.EC2, image_id string, account_id string) (boo
}

for _, lp := range attrs.LaunchPermissions {
if aws.StringValue(lp.UserId) == account_id {
if account_id != "" && aws.StringValue(lp.UserId) == account_id {
return true, nil
} else if group_name != "" && aws.StringValue(lp.Group) == group_name {
return true, nil
}
}
Expand Down
Loading