diff --git a/aws/data_source_aws_instance_test.go b/aws/data_source_aws_instance_test.go index fe48f56a516..a864173bb87 100644 --- a/aws/data_source_aws_instance_test.go +++ b/aws/data_source_aws_instance_test.go @@ -473,11 +473,7 @@ func TestAccAWSInstanceDataSource_metadataOptions(t *testing.T) { rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ - // No subnet_id specified requires default VPC or EC2-Classic. - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckHasDefaultVpcOrEc2Classic(t) - }, + PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { @@ -893,11 +889,13 @@ data "aws_instance" "test" { func testAccInstanceDataSourceConfig_metadataOptions(rName string) string { return composeConfig( testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccAwsInstanceVpcConfig(rName, false), testAccAvailableEc2InstanceTypeForRegion("t3.micro", "t2.micro"), fmt.Sprintf(` resource "aws_instance" "test" { ami = data.aws_ami.amzn-ami-minimal-hvm-ebs.id instance_type = data.aws_ec2_instance_type_offering.available.instance_type + subnet_id = aws_subnet.test.id tags = { Name = %[1]q diff --git a/aws/provider_test.go b/aws/provider_test.go index 1b9ace8063b..de1b2a3554c 100644 --- a/aws/provider_test.go +++ b/aws/provider_test.go @@ -1278,16 +1278,19 @@ func testAccCheckAWSProviderPartition(providers *[]*schema.Provider, expectedPar } } -// testAccPreCheckHasDefaultVpcOrEc2Classic checks that the test region has a default VPC or has the EC2-Classic platform. +// testAccPreCheckEc2ClassicOrHasDefaultVpcWithDefaultSubnets checks that the test region has either +// - The EC2-Classic platform available, or +// - A default VPC with default subnets. // This check is useful to ensure that an instance can be launched without specifying a subnet. -func testAccPreCheckHasDefaultVpcOrEc2Classic(t *testing.T) { +func testAccPreCheckEc2ClassicOrHasDefaultVpcWithDefaultSubnets(t *testing.T) { client := testAccProvider.Meta().(*AWSClient) - if !testAccHasDefaultVpc(t) && !hasEc2Classic(client.supportedplatforms) { - t.Skipf("skipping tests; %s does not have a default VPC or EC2-Classic", client.region) + if !hasEc2Classic(client.supportedplatforms) && !(testAccHasDefaultVpc(t) && testAccDefaultSubnetCount(t) > 0) { + t.Skipf("skipping tests; %s does not have EC2-Classic or a default VPC with default subnets", client.region) } } +// testAccHasDefaultVpc returns whether the current AWS region has a default VPC. func testAccHasDefaultVpc(t *testing.T) bool { conn := testAccProvider.Meta().(*AWSClient).ec2conn @@ -1307,6 +1310,26 @@ func testAccHasDefaultVpc(t *testing.T) bool { return true } +// testAccDefaultSubnetCount returns the number of default subnets in the current region's default VPC. +func testAccDefaultSubnetCount(t *testing.T) int { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + + input := &ec2.DescribeSubnetsInput{ + Filters: buildEC2AttributeFilterList(map[string]string{ + "defaultForAz": "true", + }), + } + output, err := conn.DescribeSubnets(input) + if testAccPreCheckSkipError(err) { + return 0 + } + if err != nil { + t.Fatalf("error describing default subnets: %s", err) + } + + return len(output.Subnets) +} + func testAccAWSProviderConfigEndpoints(endpoints string) string { //lintignore:AT004 return fmt.Sprintf(` diff --git a/aws/resource_aws_instance_test.go b/aws/resource_aws_instance_test.go index 8b7fd7316dc..e3038ff7ee4 100644 --- a/aws/resource_aws_instance_test.go +++ b/aws/resource_aws_instance_test.go @@ -151,6 +151,38 @@ func TestFetchRootDevice(t *testing.T) { } } +func TestAccAWSInstance_basic(t *testing.T) { + var v ec2.Instance + resourceName := "aws_instance.test" + + resource.ParallelTest(t, resource.TestCase{ + // No subnet_id specified requires default VPC with default subnets or EC2-Classic. + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckEc2ClassicOrHasDefaultVpcWithDefaultSubnets(t) + }, + IDRefreshName: resourceName, + Providers: testAccProviders, + CheckDestroy: testAccCheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccInstanceConfigBasic(), + Check: resource.ComposeTestCheckFunc( + testAccCheckInstanceExists(resourceName, &v), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "ec2", regexp.MustCompile(`instance/i-[a-z0-9]+`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + // Required for EC2-Classic. + ImportStateVerifyIgnore: []string{"source_dest_check"}, + }, + }, + }) +} + func TestAccAWSInstance_inDefaultVpcBySgName(t *testing.T) { var v ec2.Instance resourceName := "aws_instance.test" @@ -233,7 +265,7 @@ func TestAccAWSInstance_inEc2Classic(t *testing.T) { }) } -func TestAccAWSInstance_basic(t *testing.T) { +func TestAccAWSInstance_atLeastOneOtherEbsVolume(t *testing.T) { var v ec2.Instance var vol *ec2.Volume resourceName := "aws_instance.test" @@ -3107,11 +3139,7 @@ func TestAccAWSInstance_metadataOptions(t *testing.T) { rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ - // No subnet_id specified requires default VPC or EC2-Classic. - PreCheck: func() { - testAccPreCheck(t) - testAccPreCheckHasDefaultVpcOrEc2Classic(t) - }, + PreCheck: func() { testAccPreCheck(t) }, IDRefreshName: resourceName, Providers: testAccProviders, CheckDestroy: testAccCheckInstanceDestroy, @@ -3342,6 +3370,20 @@ data "aws_availability_zones" "current" { `, exclude) } +func testAccInstanceConfigBasic() string { + return composeConfig( + testAccLatestAmazonLinuxHvmEbsAmiConfig(), + // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-classic-platform.html#ec2-classic-instance-types + testAccAvailableEc2InstanceTypeForRegion("t1.micro", "m1.small", "t3.micro", "t2.micro"), + fmt.Sprintf(` +resource "aws_instance" "test" { + ami = data.aws_ami.amzn-ami-minimal-hvm-ebs.id + instance_type = data.aws_ec2_instance_type_offering.available.instance_type + # Explicitly no tags so as to test creation without tags. +} +`)) +} + func testAccInstanceConfigInDefaultVpcBySgName(rName string) string { return testAccLatestAmazonLinuxHvmEbsAmiConfig() + fmt.Sprintf(` data "aws_availability_zones" "current" { @@ -4945,7 +4987,7 @@ data "aws_ami" "win2016core-ami" { } // testAccAwsInstanceVpcConfig returns the configuration for tests that create -// 1) a VPC with IPv6 support +// 1) a VPC without IPv6 support // 2) a subnet in the VPC // The resources are named 'test'. func testAccAwsInstanceVpcConfig(rName string, mapPublicIpOnLaunch bool) string { @@ -5138,11 +5180,13 @@ resource "aws_instance" "test" { func testAccInstanceConfigMetadataOptions(rName string) string { return composeConfig( testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccAwsInstanceVpcConfig(rName, false), testAccAvailableEc2InstanceTypeForRegion("t3.micro", "t2.micro"), fmt.Sprintf(` resource "aws_instance" "test" { ami = data.aws_ami.amzn-ami-minimal-hvm-ebs.id instance_type = data.aws_ec2_instance_type_offering.available.instance_type + subnet_id = aws_subnet.test.id tags = { Name = %[1]q @@ -5162,11 +5206,13 @@ data "aws_instance" "test" { func testAccInstanceConfigMetadataOptionsUpdated(rName string) string { return composeConfig( testAccLatestAmazonLinuxHvmEbsAmiConfig(), + testAccAwsInstanceVpcConfig(rName, false), testAccAvailableEc2InstanceTypeForRegion("t3.micro", "t2.micro"), fmt.Sprintf(` resource "aws_instance" "test" { ami = data.aws_ami.amzn-ami-minimal-hvm-ebs.id instance_type = data.aws_ec2_instance_type_offering.available.instance_type + subnet_id = aws_subnet.test.id tags = { Name = %[1]q