mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-08 15:13:56 -06:00
fcec0a9f3d
Previously the AMI creation accepted a static value for the AMI's block device's volume size. This change allows the user to omit the `volume_size` attribute, in order to mimic the AWS API behavior, which will use the EBS Volume's size. Also fixes a potential panic case when setting `iops` on the AMI's block device. The `aws_ami` resource previously didn't have any acceptance tests, adds two acceptance tests and a full testing suite for the `aws_ami` resource, so further tests can be written, as well as expansion upon the other `aws_ami_*` acceptance tests ``` $ make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSAMI_' ==> Checking that code complies with gofmt requirements... go generate $(go list ./... | grep -v /terraform/vendor/) 2017/02/09 20:18:22 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSAMI_ -timeout 120m === RUN TestAccAWSAMI_basic --- PASS: TestAccAWSAMI_basic (44.21s) === RUN TestAccAWSAMI_snapshotSize --- PASS: TestAccAWSAMI_snapshotSize (45.08s) PASS ok github.com/hashicorp/terraform/builtin/providers/aws 89.320s ```
231 lines
5.8 KiB
Go
231 lines
5.8 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 {
|
|
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 = "tf-acc-test"
|
|
}
|
|
}
|
|
|
|
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 = "tf-acc-test"
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|