github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_ami_from_instance_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/ec2"
    12  	"github.com/hashicorp/terraform/helper/acctest"
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/terraform"
    15  )
    16  
    17  func TestAccAWSAMIFromInstance(t *testing.T) {
    18  	var amiId string
    19  	snapshots := []string{}
    20  	rInt := acctest.RandInt()
    21  
    22  	resource.Test(t, resource.TestCase{
    23  		PreCheck:  func() { testAccPreCheck(t) },
    24  		Providers: testAccProviders,
    25  		Steps: []resource.TestStep{
    26  			{
    27  				Config: testAccAWSAMIFromInstanceConfig(rInt),
    28  				Check: func(state *terraform.State) error {
    29  					rs, ok := state.RootModule().Resources["aws_ami_from_instance.test"]
    30  					if !ok {
    31  						return fmt.Errorf("AMI resource not found")
    32  					}
    33  
    34  					amiId = rs.Primary.ID
    35  
    36  					if amiId == "" {
    37  						return fmt.Errorf("AMI id is not set")
    38  					}
    39  
    40  					conn := testAccProvider.Meta().(*AWSClient).ec2conn
    41  					req := &ec2.DescribeImagesInput{
    42  						ImageIds: []*string{aws.String(amiId)},
    43  					}
    44  					describe, err := conn.DescribeImages(req)
    45  					if err != nil {
    46  						return err
    47  					}
    48  
    49  					if len(describe.Images) != 1 ||
    50  						*describe.Images[0].ImageId != rs.Primary.ID {
    51  						return fmt.Errorf("AMI not found")
    52  					}
    53  
    54  					image := describe.Images[0]
    55  					if expected := "available"; *image.State != expected {
    56  						return fmt.Errorf("invalid image state; expected %v, got %v", expected, *image.State)
    57  					}
    58  					if expected := "machine"; *image.ImageType != expected {
    59  						return fmt.Errorf("wrong image type; expected %v, got %v", expected, *image.ImageType)
    60  					}
    61  					if expected := fmt.Sprintf("terraform-acc-ami-from-instance-%d", rInt); *image.Name != expected {
    62  						return fmt.Errorf("wrong name; expected %v, got %v", expected, *image.Name)
    63  					}
    64  
    65  					for _, bdm := range image.BlockDeviceMappings {
    66  						if bdm.Ebs != nil && bdm.Ebs.SnapshotId != nil {
    67  							snapshots = append(snapshots, *bdm.Ebs.SnapshotId)
    68  						}
    69  					}
    70  
    71  					if expected := 1; len(snapshots) != expected {
    72  						return fmt.Errorf("wrong number of snapshots; expected %v, got %v", expected, len(snapshots))
    73  					}
    74  
    75  					return nil
    76  				},
    77  			},
    78  		},
    79  		CheckDestroy: func(state *terraform.State) error {
    80  			conn := testAccProvider.Meta().(*AWSClient).ec2conn
    81  			diReq := &ec2.DescribeImagesInput{
    82  				ImageIds: []*string{aws.String(amiId)},
    83  			}
    84  			diRes, err := conn.DescribeImages(diReq)
    85  			if err != nil {
    86  				return err
    87  			}
    88  
    89  			if len(diRes.Images) > 0 {
    90  				state := diRes.Images[0].State
    91  				return fmt.Errorf("AMI %v remains in state %v", amiId, state)
    92  			}
    93  
    94  			stillExist := make([]string, 0, len(snapshots))
    95  			checkErrors := make(map[string]error)
    96  			for _, snapshotId := range snapshots {
    97  				dsReq := &ec2.DescribeSnapshotsInput{
    98  					SnapshotIds: []*string{aws.String(snapshotId)},
    99  				}
   100  				_, err := conn.DescribeSnapshots(dsReq)
   101  				if err == nil {
   102  					stillExist = append(stillExist, snapshotId)
   103  					continue
   104  				}
   105  
   106  				awsErr, ok := err.(awserr.Error)
   107  				if !ok {
   108  					checkErrors[snapshotId] = err
   109  					continue
   110  				}
   111  
   112  				if awsErr.Code() != "InvalidSnapshot.NotFound" {
   113  					checkErrors[snapshotId] = err
   114  					continue
   115  				}
   116  			}
   117  
   118  			if len(stillExist) > 0 || len(checkErrors) > 0 {
   119  				errParts := []string{
   120  					"Expected all snapshots to be gone, but:",
   121  				}
   122  				for _, snapshotId := range stillExist {
   123  					errParts = append(
   124  						errParts,
   125  						fmt.Sprintf("- %v still exists", snapshotId),
   126  					)
   127  				}
   128  				for snapshotId, err := range checkErrors {
   129  					errParts = append(
   130  						errParts,
   131  						fmt.Sprintf("- checking %v gave error: %v", snapshotId, err),
   132  					)
   133  				}
   134  				return errors.New(strings.Join(errParts, "\n"))
   135  			}
   136  
   137  			return nil
   138  		},
   139  	})
   140  }
   141  
   142  func testAccAWSAMIFromInstanceConfig(rInt int) string {
   143  	return fmt.Sprintf(`
   144  	provider "aws" {
   145  		region = "us-east-1"
   146  	}
   147  
   148  	resource "aws_instance" "test" {
   149  			// This AMI has one block device mapping, so we expect to have
   150  			// one snapshot in our created AMI.
   151  			ami = "ami-408c7f28"
   152  			instance_type = "t1.micro"
   153  			tags {
   154  				Name = "testAccAWSAMIFromInstanceConfig_TestAMI"
   155  			}
   156  	}
   157  
   158  	resource "aws_ami_from_instance" "test" {
   159  			name = "terraform-acc-ami-from-instance-%d"
   160  			description = "Testing Terraform aws_ami_from_instance resource"
   161  			source_instance_id = "${aws_instance.test.id}"
   162  	}`, rInt)
   163  }