terraform/builtin/providers/aws/resource_aws_ami_test.go

235 lines
5.9 KiB
Go

package aws
import (
"fmt"
"log"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccAWSAMI_basic(t *testing.T) {
var ami ec2.Image
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAmiDestroy,
Steps: []resource.TestStep{
{
Config: testAccAmiConfig_basic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAmiExists("aws_ami.foo", &ami),
resource.TestCheckResourceAttr(
"aws_ami.foo", "name", fmt.Sprintf("tf-testing-%d", rInt)),
),
},
},
})
}
func TestAccAWSAMI_snapshotSize(t *testing.T) {
var ami ec2.Image
var bd ec2.BlockDeviceMapping
rInt := acctest.RandInt()
expectedDevice := &ec2.EbsBlockDevice{
DeleteOnTermination: aws.Bool(true),
Encrypted: aws.Bool(false),
Iops: aws.Int64(0),
VolumeSize: aws.Int64(20),
VolumeType: aws.String("standard"),
}
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAmiDestroy,
Steps: []resource.TestStep{
{
Config: testAccAmiConfig_snapshotSize(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAmiExists("aws_ami.foo", &ami),
testAccCheckAmiBlockDevice(&ami, &bd, "/dev/sda1"),
testAccCheckAmiEbsBlockDevice(&bd, expectedDevice),
resource.TestCheckResourceAttr(
"aws_ami.foo", "name", fmt.Sprintf("tf-testing-%d", rInt)),
resource.TestCheckResourceAttr(
"aws_ami.foo", "architecture", "x86_64"),
),
},
},
})
}
func testAccCheckAmiDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_ami" {
continue
}
// Try to find the AMI
log.Printf("AMI-ID: %s", rs.Primary.ID)
DescribeAmiOpts := &ec2.DescribeImagesInput{
ImageIds: []*string{aws.String(rs.Primary.ID)},
}
resp, err := conn.DescribeImages(DescribeAmiOpts)
if err != nil {
if isAWSErr(err, "InvalidAMIID", "NotFound") {
log.Printf("[DEBUG] AMI not found, passing")
return nil
}
return err
}
if len(resp.Images) > 0 {
state := resp.Images[0].State
return fmt.Errorf("AMI %s still exists in the state: %s.", *resp.Images[0].ImageId, *state)
}
}
return nil
}
func testAccCheckAmiExists(n string, ami *ec2.Image) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("AMI Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No AMI ID is set")
}
conn := testAccProvider.Meta().(*AWSClient).ec2conn
opts := &ec2.DescribeImagesInput{
ImageIds: []*string{aws.String(rs.Primary.ID)},
}
resp, err := conn.DescribeImages(opts)
if err != nil {
return err
}
if len(resp.Images) == 0 {
return fmt.Errorf("AMI not found")
}
*ami = *resp.Images[0]
return nil
}
}
func testAccCheckAmiBlockDevice(ami *ec2.Image, blockDevice *ec2.BlockDeviceMapping, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
devices := make(map[string]*ec2.BlockDeviceMapping)
for _, device := range ami.BlockDeviceMappings {
devices[*device.DeviceName] = device
}
// Check if the block device exists
if _, ok := devices[n]; !ok {
return fmt.Errorf("block device doesn't exist: %s", n)
}
*blockDevice = *devices[n]
return nil
}
}
func testAccCheckAmiEbsBlockDevice(bd *ec2.BlockDeviceMapping, ed *ec2.EbsBlockDevice) resource.TestCheckFunc {
return func(s *terraform.State) error {
// Test for things that ed has, don't care about unset values
cd := bd.Ebs
if ed.VolumeType != nil {
if *ed.VolumeType != *cd.VolumeType {
return fmt.Errorf("Volume type mismatch. Expected: %s Got: %s",
*ed.VolumeType, *cd.VolumeType)
}
}
if ed.DeleteOnTermination != nil {
if *ed.DeleteOnTermination != *cd.DeleteOnTermination {
return fmt.Errorf("DeleteOnTermination mismatch. Expected: %t Got: %t",
*ed.DeleteOnTermination, *cd.DeleteOnTermination)
}
}
if ed.Encrypted != nil {
if *ed.Encrypted != *cd.Encrypted {
return fmt.Errorf("Encrypted mismatch. Expected: %t Got: %t",
*ed.Encrypted, *cd.Encrypted)
}
}
// Integer defaults need to not be `0` so we don't get a panic
if ed.Iops != nil && *ed.Iops != 0 {
if *ed.Iops != *cd.Iops {
return fmt.Errorf("IOPS mismatch. Expected: %d Got: %d",
*ed.Iops, *cd.Iops)
}
}
if ed.VolumeSize != nil && *ed.VolumeSize != 0 {
if *ed.VolumeSize != *cd.VolumeSize {
return fmt.Errorf("Volume Size mismatch. Expected: %d Got: %d",
*ed.VolumeSize, *cd.VolumeSize)
}
}
return nil
}
}
func testAccAmiConfig_basic(rInt int) string {
return fmt.Sprintf(`
resource "aws_ebs_volume" "foo" {
availability_zone = "us-west-2a"
size = 8
tags {
Name = "testAccAmiConfig_basic"
}
}
resource "aws_ebs_snapshot" "foo" {
volume_id = "${aws_ebs_volume.foo.id}"
}
resource "aws_ami" "foo" {
name = "tf-testing-%d"
virtualization_type = "hvm"
root_device_name = "/dev/sda1"
ebs_block_device {
device_name = "/dev/sda1"
snapshot_id = "${aws_ebs_snapshot.foo.id}"
}
}
`, rInt)
}
func testAccAmiConfig_snapshotSize(rInt int) string {
return fmt.Sprintf(`
resource "aws_ebs_volume" "foo" {
availability_zone = "us-west-2a"
size = 20
tags {
Name = "testAccAmiConfig_snapshotSize"
}
}
resource "aws_ebs_snapshot" "foo" {
volume_id = "${aws_ebs_volume.foo.id}"
}
resource "aws_ami" "foo" {
name = "tf-testing-%d"
virtualization_type = "hvm"
root_device_name = "/dev/sda1"
ebs_block_device {
device_name = "/dev/sda1"
snapshot_id = "${aws_ebs_snapshot.foo.id}"
}
}
`, rInt)
}