github.com/jrperritt/terraform@v0.1.1-0.20170525065507-96f391dafc38/builtin/providers/aws/resource_aws_ami_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"testing"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/ec2"
    10  	"github.com/hashicorp/terraform/helper/acctest"
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/terraform"
    13  )
    14  
    15  func TestAccAWSAMI_basic(t *testing.T) {
    16  	var ami ec2.Image
    17  	rInt := acctest.RandInt()
    18  
    19  	resource.Test(t, resource.TestCase{
    20  		PreCheck:     func() { testAccPreCheck(t) },
    21  		Providers:    testAccProviders,
    22  		CheckDestroy: testAccCheckAmiDestroy,
    23  		Steps: []resource.TestStep{
    24  			{
    25  				Config: testAccAmiConfig_basic(rInt),
    26  				Check: resource.ComposeTestCheckFunc(
    27  					testAccCheckAmiExists("aws_ami.foo", &ami),
    28  					resource.TestCheckResourceAttr(
    29  						"aws_ami.foo", "name", fmt.Sprintf("tf-testing-%d", rInt)),
    30  				),
    31  			},
    32  		},
    33  	})
    34  }
    35  
    36  func TestAccAWSAMI_snapshotSize(t *testing.T) {
    37  	var ami ec2.Image
    38  	var bd ec2.BlockDeviceMapping
    39  	rInt := acctest.RandInt()
    40  
    41  	expectedDevice := &ec2.EbsBlockDevice{
    42  		DeleteOnTermination: aws.Bool(true),
    43  		Encrypted:           aws.Bool(false),
    44  		Iops:                aws.Int64(0),
    45  		VolumeSize:          aws.Int64(20),
    46  		VolumeType:          aws.String("standard"),
    47  	}
    48  
    49  	resource.Test(t, resource.TestCase{
    50  		PreCheck:     func() { testAccPreCheck(t) },
    51  		Providers:    testAccProviders,
    52  		CheckDestroy: testAccCheckAmiDestroy,
    53  		Steps: []resource.TestStep{
    54  			{
    55  				Config: testAccAmiConfig_snapshotSize(rInt),
    56  				Check: resource.ComposeTestCheckFunc(
    57  					testAccCheckAmiExists("aws_ami.foo", &ami),
    58  					testAccCheckAmiBlockDevice(&ami, &bd, "/dev/sda1"),
    59  					testAccCheckAmiEbsBlockDevice(&bd, expectedDevice),
    60  					resource.TestCheckResourceAttr(
    61  						"aws_ami.foo", "name", fmt.Sprintf("tf-testing-%d", rInt)),
    62  					resource.TestCheckResourceAttr(
    63  						"aws_ami.foo", "architecture", "x86_64"),
    64  				),
    65  			},
    66  		},
    67  	})
    68  }
    69  
    70  func testAccCheckAmiDestroy(s *terraform.State) error {
    71  	conn := testAccProvider.Meta().(*AWSClient).ec2conn
    72  
    73  	for _, rs := range s.RootModule().Resources {
    74  		if rs.Type != "aws_ami" {
    75  			continue
    76  		}
    77  
    78  		// Try to find the AMI
    79  		log.Printf("AMI-ID: %s", rs.Primary.ID)
    80  		DescribeAmiOpts := &ec2.DescribeImagesInput{
    81  			ImageIds: []*string{aws.String(rs.Primary.ID)},
    82  		}
    83  		resp, err := conn.DescribeImages(DescribeAmiOpts)
    84  		if err != nil {
    85  			if isAWSErr(err, "InvalidAMIID", "NotFound") {
    86  				log.Printf("[DEBUG] AMI not found, passing")
    87  				return nil
    88  			}
    89  			return err
    90  		}
    91  
    92  		if len(resp.Images) > 0 {
    93  			state := resp.Images[0].State
    94  			return fmt.Errorf("AMI %s still exists in the state: %s.", *resp.Images[0].ImageId, *state)
    95  		}
    96  	}
    97  	return nil
    98  }
    99  
   100  func testAccCheckAmiExists(n string, ami *ec2.Image) resource.TestCheckFunc {
   101  	return func(s *terraform.State) error {
   102  		rs, ok := s.RootModule().Resources[n]
   103  		if !ok {
   104  			return fmt.Errorf("AMI Not found: %s", n)
   105  		}
   106  
   107  		if rs.Primary.ID == "" {
   108  			return fmt.Errorf("No AMI ID is set")
   109  		}
   110  
   111  		conn := testAccProvider.Meta().(*AWSClient).ec2conn
   112  		opts := &ec2.DescribeImagesInput{
   113  			ImageIds: []*string{aws.String(rs.Primary.ID)},
   114  		}
   115  		resp, err := conn.DescribeImages(opts)
   116  		if err != nil {
   117  			return err
   118  		}
   119  		if len(resp.Images) == 0 {
   120  			return fmt.Errorf("AMI not found")
   121  		}
   122  		*ami = *resp.Images[0]
   123  		return nil
   124  	}
   125  }
   126  
   127  func testAccCheckAmiBlockDevice(ami *ec2.Image, blockDevice *ec2.BlockDeviceMapping, n string) resource.TestCheckFunc {
   128  	return func(s *terraform.State) error {
   129  		devices := make(map[string]*ec2.BlockDeviceMapping)
   130  		for _, device := range ami.BlockDeviceMappings {
   131  			devices[*device.DeviceName] = device
   132  		}
   133  
   134  		// Check if the block device exists
   135  		if _, ok := devices[n]; !ok {
   136  			return fmt.Errorf("block device doesn't exist: %s", n)
   137  		}
   138  
   139  		*blockDevice = *devices[n]
   140  		return nil
   141  	}
   142  }
   143  
   144  func testAccCheckAmiEbsBlockDevice(bd *ec2.BlockDeviceMapping, ed *ec2.EbsBlockDevice) resource.TestCheckFunc {
   145  	return func(s *terraform.State) error {
   146  		// Test for things that ed has, don't care about unset values
   147  		cd := bd.Ebs
   148  		if ed.VolumeType != nil {
   149  			if *ed.VolumeType != *cd.VolumeType {
   150  				return fmt.Errorf("Volume type mismatch. Expected: %s Got: %s",
   151  					*ed.VolumeType, *cd.VolumeType)
   152  			}
   153  		}
   154  		if ed.DeleteOnTermination != nil {
   155  			if *ed.DeleteOnTermination != *cd.DeleteOnTermination {
   156  				return fmt.Errorf("DeleteOnTermination mismatch. Expected: %t Got: %t",
   157  					*ed.DeleteOnTermination, *cd.DeleteOnTermination)
   158  			}
   159  		}
   160  		if ed.Encrypted != nil {
   161  			if *ed.Encrypted != *cd.Encrypted {
   162  				return fmt.Errorf("Encrypted mismatch. Expected: %t Got: %t",
   163  					*ed.Encrypted, *cd.Encrypted)
   164  			}
   165  		}
   166  		// Integer defaults need to not be `0` so we don't get a panic
   167  		if ed.Iops != nil && *ed.Iops != 0 {
   168  			if *ed.Iops != *cd.Iops {
   169  				return fmt.Errorf("IOPS mismatch. Expected: %d Got: %d",
   170  					*ed.Iops, *cd.Iops)
   171  			}
   172  		}
   173  		if ed.VolumeSize != nil && *ed.VolumeSize != 0 {
   174  			if *ed.VolumeSize != *cd.VolumeSize {
   175  				return fmt.Errorf("Volume Size mismatch. Expected: %d Got: %d",
   176  					*ed.VolumeSize, *cd.VolumeSize)
   177  			}
   178  		}
   179  
   180  		return nil
   181  	}
   182  }
   183  
   184  func testAccAmiConfig_basic(rInt int) string {
   185  	return fmt.Sprintf(`
   186  resource "aws_ebs_volume" "foo" {
   187   	availability_zone = "us-west-2a"
   188   	size = 8
   189   	tags {
   190   	  Name = "testAccAmiConfig_basic"
   191   	}
   192  }
   193  
   194  resource "aws_ebs_snapshot" "foo" {
   195    volume_id = "${aws_ebs_volume.foo.id}"
   196  }
   197  
   198  resource "aws_ami" "foo" {
   199    name = "tf-testing-%d"
   200    virtualization_type = "hvm"
   201    root_device_name = "/dev/sda1"
   202    ebs_block_device {
   203      device_name = "/dev/sda1"
   204      snapshot_id = "${aws_ebs_snapshot.foo.id}"
   205    }
   206  }
   207  	`, rInt)
   208  }
   209  
   210  func testAccAmiConfig_snapshotSize(rInt int) string {
   211  	return fmt.Sprintf(`
   212  resource "aws_ebs_volume" "foo" {
   213   	availability_zone = "us-west-2a"
   214   	size = 20
   215   	tags {
   216   	  Name = "testAccAmiConfig_snapshotSize"
   217   	}
   218  }
   219  
   220  resource "aws_ebs_snapshot" "foo" {
   221    volume_id = "${aws_ebs_volume.foo.id}"
   222  }
   223  
   224  resource "aws_ami" "foo" {
   225    name = "tf-testing-%d"
   226    virtualization_type = "hvm"
   227    root_device_name = "/dev/sda1"
   228    ebs_block_device {
   229      device_name = "/dev/sda1"
   230      snapshot_id = "${aws_ebs_snapshot.foo.id}"
   231    }
   232  }
   233  	`, rInt)
   234  }