-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementing aws_ami_launch_permission.
- Loading branch information
Brad Sickles
committed
Jun 27, 2016
1 parent
b68eca5
commit 0b17c69
Showing
5 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
builtin/providers/aws/resource_aws_ami_launch_permission.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsAmiLaunchPermission() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsAmiLaunchPermissionCreate, | ||
Read: resourceAwsAmiLaunchPermissionRead, | ||
Update: resourceAwsAmiLaunchPermissionUpdate, | ||
Delete: resourceAwsAmiLaunchPermissionDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"image_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"account_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsAmiLaunchPermissionCreate(d *schema.ResourceData, meta interface{}) error { | ||
err := resourceAwsAmiLaunchPermissionUpdate(d, meta) | ||
if err != nil { | ||
return err | ||
} | ||
image_id := d.Get("image_id").(string) | ||
account_id := d.Get("account_id").(string) | ||
d.SetId(fmt.Sprintf("%s-%s", image_id, account_id)) | ||
return nil | ||
} | ||
|
||
func resourceAwsAmiLaunchPermissionRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).ec2conn | ||
|
||
image_id := d.Get("image_id").(string) | ||
account_id := d.Get("account_id").(string) | ||
has, err := hasLaunchPermission(conn, image_id, account_id) | ||
if err != nil { | ||
return fmt.Errorf("error reading ami launch permission: %s", err) | ||
} | ||
if !has { | ||
d.Set("account_id", "") | ||
d.SetId("") | ||
d.MarkNewResource() | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsAmiLaunchPermissionUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).ec2conn | ||
|
||
image_id := d.Get("image_id").(string) | ||
oldv, newv := d.GetChange("account_id") | ||
|
||
toAdd := []*ec2.LaunchPermission{} | ||
if old_account_id, ok := oldv.(string); ok { | ||
toAdd = append(toAdd, &ec2.LaunchPermission{UserId: aws.String(old_account_id)}) | ||
} | ||
|
||
toRemove := []*ec2.LaunchPermission{} | ||
if new_account_id, ok := newv.(string); ok { | ||
toRemove = append(toRemove, &ec2.LaunchPermission{UserId: aws.String(new_account_id)}) | ||
} | ||
|
||
_, err := conn.ModifyImageAttribute(&ec2.ModifyImageAttributeInput{ | ||
ImageId: aws.String(image_id), | ||
Attribute: aws.String("launchPermission"), | ||
LaunchPermission: &ec2.LaunchPermissionModifications{ | ||
Add: toAdd, | ||
Remove: toRemove, | ||
}, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error updating ami launch permission: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsAmiLaunchPermissionDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).ec2conn | ||
|
||
image_id := d.Get("image_id").(string) | ||
account_id := d.Get("account_id").(string) | ||
|
||
_, err := conn.ModifyImageAttribute(&ec2.ModifyImageAttributeInput{ | ||
ImageId: aws.String(image_id), | ||
Attribute: aws.String("launchPermission"), | ||
LaunchPermission: &ec2.LaunchPermissionModifications{ | ||
Remove: []*ec2.LaunchPermission{ | ||
&ec2.LaunchPermission{UserId: aws.String(account_id)}, | ||
}, | ||
}, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("error removing ami launch permission: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func hasLaunchPermission(conn *ec2.EC2, image_id string, account_id string) (bool, error) { | ||
attrs, err := conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{ | ||
ImageId: aws.String(image_id), | ||
Attribute: aws.String("launchPermission"), | ||
}) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
for _, lp := range attrs.LaunchPermissions { | ||
if *lp.UserId == account_id { | ||
return true, nil | ||
} | ||
} | ||
return false, nil | ||
} |
138 changes: 138 additions & 0 deletions
138
builtin/providers/aws/resource_aws_ami_launch_permission_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/ec2" | ||
"github.com/aws/aws-sdk-go/service/sts" | ||
r "github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
"testing" | ||
) | ||
|
||
func TestAccAWSAMILaunchPermission_Basic(t *testing.T) { | ||
conn := testAccProvider.Meta().(*AWSClient).stsconn | ||
res, err := conn.GetCallerIdentity(&sts.GetCallerIdentityInput{}) | ||
if err != nil { | ||
t.Fatalf("could not initialize ami launch permission test: %s", err) | ||
} | ||
|
||
var amiId string | ||
r.Test(t, r.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
Steps: []r.TestStep{ | ||
r.TestStep{ | ||
Config: testAccAWSAMILaunchPermissionConfig(*res.Account), | ||
Check: r.ComposeTestCheckFunc( | ||
testCheckResourceGetAttr("aws_ami_from_instance", "id", &amiId), | ||
testAccAWSAMILaunchPermissionExists(amiId, *res.Account), | ||
), | ||
}, | ||
}, | ||
CheckDestroy: testAccAWSAMILaunchPermissionDestroyed(), | ||
}) | ||
} | ||
|
||
func testCheckResourceGetAttr(name, key string, value *string) r.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
ms := s.RootModule() | ||
rs, ok := ms.Resources[name] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", name) | ||
} | ||
|
||
is := rs.Primary | ||
if is == nil { | ||
return fmt.Errorf("No primary instance: %s", name) | ||
} | ||
|
||
*value = is.Attributes[key] | ||
return nil | ||
} | ||
} | ||
|
||
func testAccAWSAMILaunchPermissionExists(amiId string, accountId string) r.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).ec2conn | ||
res, err := conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{ | ||
ImageId: aws.String(amiId), | ||
Attribute: aws.String("launchPermission"), | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
for _, lp := range res.LaunchPermissions { | ||
if *lp.UserId == accountId { | ||
return nil | ||
} | ||
} | ||
return fmt.Errorf("launch permission does not exist for '%s' on '%s'", accountId, amiId) | ||
} | ||
} | ||
|
||
func testAccAWSAMILaunchPermissionDestroyed() r.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).ec2conn | ||
|
||
conn.DescribeImageAttribute(&ec2.DescribeImageAttributeInput{ | ||
ImageId: aws.String(""), | ||
}) | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccAWSAMILaunchPermissionConfig(accountId string) string { | ||
return fmt.Sprintf(` | ||
provider "aws" { | ||
region = "us-east-1" | ||
} | ||
// We don't have an AMI to use, so we can scaffold one on-the-fly | ||
// - Spin up an EC2 instance based on a public AMI | ||
// - Create an AMI by snapshotting that EC2 instance, using | ||
// aws_ami_from_instance . | ||
// - Attach aws_ami_launch_permission to resulting AMI | ||
// | ||
// Thus this test can only succeed if the aws_ami_from_instance resource | ||
// is working. If it's misbehaving it will likely cause this test to fail too. | ||
// Since we're booting a t2.micro HVM instance we need a VPC for it to boot | ||
// up into. | ||
resource "aws_vpc" "foo" { | ||
cidr_block = "10.2.0.0/16" | ||
} | ||
resource "aws_subnet" "foo" { | ||
cidr_block = "10.2.1.0/24" | ||
vpc_id = "${aws_vpc.foo.id}" | ||
} | ||
resource "aws_instance" "test" { | ||
// This AMI has one block device mapping, so we expect to have | ||
// one snapshot in our created AMI. | ||
// This is an Ubuntu Linux HVM AMI. A public HVM AMI is required | ||
// because paravirtual images cannot be copied between accounts. | ||
ami = "ami-0f8bce65" | ||
instance_type = "t2.micro" | ||
tags { | ||
Name = "terraform-acc-ami-launch-permission-victim" | ||
} | ||
subnet_id = "${aws_subnet.foo.id}" | ||
} | ||
resource "aws_ami_from_instance" "test" { | ||
name = "terraform-acc-ami-launch-permission-victim" | ||
description = "Testing Terraform aws_ami_from_instance resource" | ||
source_instance_id = "${aws_instance.test.id}" | ||
} | ||
resource "aws_ami_launch_permission" "self-test" { | ||
image_id = "${aws_ami_from_instance.test.id}" | ||
account_id = "%s" | ||
} | ||
`, accountId) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
website/source/docs/providers/aws/r/ami_launch_permission.html.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
layout: "aws" | ||
page_title: "AWS: aws_ami_launch_permission" | ||
sidebar_current: "docs-aws-resource-ami-launch-permission" | ||
description: |- | ||
Adds launch permission to Amazon Machine Image (AMI). | ||
--- | ||
|
||
# aws\_ami\_launch\_permission | ||
|
||
Adds launch permission to Amazon Machine Image (AMI) from another AWS account. | ||
|
||
## Example Usage | ||
|
||
``` | ||
resource "aws_ami_launch_permission" "example" { | ||
image_id = "ami-12345678" | ||
account_id = "123456789012" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `image_id` - (required) A region-unique name for the AMI. | ||
* `account_id` - (required) An AWS Account ID to add launch permissions. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
* `id` - A combination of "`image_id`-`account_id`". |