Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resource/aws_opsworks_stack: Use Default VPC when no VPC ID passed #26711

Merged
merged 3 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/26711.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_opsworks_stack: Defaults to default VPC when not supplied
```
2 changes: 1 addition & 1 deletion internal/acctest/acctest.go
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ func PreCheckRegionNot(t *testing.T, regions ...string) {
// PreCheckAlternateRegionIs checks that the alternate test region is the specified region.
func PreCheckAlternateRegionIs(t *testing.T, region string) {
if curr := AlternateRegion(); curr != region {
t.Skipf("skipping tests; %s (%s) does not equal %s", conns.EnvVarDefaultRegion, curr, region)
t.Skipf("skipping tests; %s (%s) does not equal %s", conns.EnvVarAlternateRegion, curr, region)
}
}

Expand Down
2 changes: 1 addition & 1 deletion internal/service/acm/sweep.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func sweepCertificates(region string) error {
for _, iub := range output.Certificate.InUseBy {
m[aws.StringValue(iub)[:77]] = ""
}
for k, _ := range m {
for k := range m {
log.Printf("[INFO] %s...", k)
}
continue
Expand Down
2 changes: 0 additions & 2 deletions internal/service/ec2/vpc_security_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2498,7 +2498,6 @@ resource "aws_security_group" "test" {
data "aws_vpc" "default" {
default = true
}

`, rName)
}

Expand All @@ -2512,7 +2511,6 @@ resource "aws_security_group" "test" {
data "aws_vpc" "default" {
default = true
}

`, rName)
}

Expand Down
23 changes: 9 additions & 14 deletions internal/service/opsworks/stack.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package opsworks

import (
"errors"
"fmt"
"log"
"time"
Expand Down Expand Up @@ -112,10 +111,10 @@ func ResourceStack() *schema.Resource {
DiffSuppressFunc: verify.SuppressEquivalentJSONDiffs,
},
"default_availability_zone": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ExactlyOneOf: []string{"default_availability_zone", "vpc_id"},
Type: schema.TypeString,
Optional: true,
Computed: true,
ConflictsWith: []string{"vpc_id"},
},
"default_instance_profile_arn": {
Type: schema.TypeString,
Expand Down Expand Up @@ -182,11 +181,11 @@ func ResourceStack() *schema.Resource {
Default: true,
},
"vpc_id": {
Type: schema.TypeString,
ForceNew: true,
Computed: true,
Optional: true,
ExactlyOneOf: []string{"default_availability_zone", "vpc_id"},
Type: schema.TypeString,
ForceNew: true,
Computed: true,
Optional: true,
ConflictsWith: []string{"default_availability_zone"},
},
},

Expand All @@ -199,10 +198,6 @@ func resourceStackCreate(d *schema.ResourceData, meta interface{}) error {
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

if _, ok := d.GetOk("vpc_id"); !ok {
return errors.New(`with the retirement of EC2-Classic no new OpsWorks Stacks can be created without referencing a VPC`)
}

name := d.Get("name").(string)
region := d.Get("region").(string)
input := &opsworks.CreateStackInput{
Expand Down
140 changes: 137 additions & 3 deletions internal/service/opsworks/stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,80 @@ func TestAccOpsWorksStack_disappears(t *testing.T) {
})
}

func TestAccOpsWorksStack_noVPC_basic(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_opsworks_stack.test"
var v opsworks.Stack

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(t)
acctest.PreCheckPartitionHasService(opsworks.EndpointsID, t)
testAccPreCheckStacks(t)
},
ErrorCheck: acctest.ErrorCheck(t, opsworks.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckStackDestroy,
Steps: []resource.TestStep{
{
Config: testAccStackConfig_noVPC(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckStackExists(resourceName, &v),
resource.TestMatchResourceAttr(resourceName, "default_availability_zone", regexp.MustCompile(fmt.Sprintf("%s[a-z]", acctest.Region()))),
resource.TestMatchResourceAttr(resourceName, "default_subnet_id", regexp.MustCompile("subnet-[[:alnum:]]")),
resource.TestCheckResourceAttrPair(resourceName, "vpc_id", "data.aws_vpc.default", "id"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccStackConfig_defaultVPC(rName),
PlanOnly: true,
},
{
Config: testAccStackConfig_noVPC(rName),
PlanOnly: true,
},
},
})
}

func TestAccOpsWorksStack_noVPC_defaultAZ(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_opsworks_stack.test"
var v opsworks.Stack

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(t)
acctest.PreCheckPartitionHasService(opsworks.EndpointsID, t)
testAccPreCheckStacks(t)
},
ErrorCheck: acctest.ErrorCheck(t, opsworks.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckStackDestroy,
Steps: []resource.TestStep{
{
Config: testAccStackConfig_noVPCDefaultAZ(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckStackExists(resourceName, &v),
resource.TestCheckResourceAttrPair(resourceName, "default_availability_zone", "data.aws_availability_zones.available", "names.1"),
resource.TestMatchResourceAttr(resourceName, "default_subnet_id", regexp.MustCompile("subnet-[[:alnum:]]")),
resource.TestCheckResourceAttrPair(resourceName, "vpc_id", "data.aws_vpc.default", "id"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccOpsWorksStack_tags(t *testing.T) {
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_opsworks_stack.test"
Expand Down Expand Up @@ -461,7 +535,7 @@ func testAccCheckStackDestroy(s *terraform.State) error {
return nil
}

func testAccStackConfig_base(rName string) string {
func testAccStackConfig_baseIAM(rName string) string {
return fmt.Sprintf(`
resource "aws_iam_role" "opsworks_service" {
name = "%[1]s-service"
Expand Down Expand Up @@ -527,13 +601,16 @@ resource "aws_iam_instance_profile" "opsworks_instance" {
}

func testAccStackConfig_baseVPC(rName string) string {
return acctest.ConfigCompose(testAccStackConfig_base(rName), acctest.ConfigVPCWithSubnets(rName, 2))
return acctest.ConfigCompose(
testAccStackConfig_baseIAM(rName),
acctest.ConfigVPCWithSubnets(rName, 2),
)
}

func testAccStackConfig_baseVPCAlternateRegion(rName string) string {
return acctest.ConfigCompose(
acctest.ConfigMultipleRegionProvider(2),
testAccStackConfig_base(rName),
testAccStackConfig_baseIAM(rName),
fmt.Sprintf(`
# The VPC (and subnets) must be in the target (alternate) AWS Region.
data "aws_availability_zones" "available" {
Expand Down Expand Up @@ -587,6 +664,63 @@ resource "aws_opsworks_stack" "test" {
`, rName, acctest.Region()))
}

func testAccStackConfig_noVPC(rName string) string {
return acctest.ConfigCompose(
testAccStackConfig_baseIAM(rName),
fmt.Sprintf(`
resource "aws_opsworks_stack" "test" {
name = %[1]q
region = %[2]q
service_role_arn = aws_iam_role.opsworks_service.arn
default_instance_profile_arn = aws_iam_instance_profile.opsworks_instance.arn
use_opsworks_security_groups = false
}

data "aws_vpc" "default" {
default = true
}
`, rName, acctest.Region()))
}

func testAccStackConfig_defaultVPC(rName string) string {
return acctest.ConfigCompose(
testAccStackConfig_baseIAM(rName),
fmt.Sprintf(`
resource "aws_opsworks_stack" "test" {
name = %[1]q
region = %[2]q
service_role_arn = aws_iam_role.opsworks_service.arn
default_instance_profile_arn = aws_iam_instance_profile.opsworks_instance.arn
use_opsworks_security_groups = false
vpc_id = data.aws_vpc.default.id
}

data "aws_vpc" "default" {
default = true
}
`, rName, acctest.Region()))
}

func testAccStackConfig_noVPCDefaultAZ(rName string) string {
return acctest.ConfigCompose(
testAccStackConfig_baseIAM(rName),
acctest.ConfigAvailableAZsNoOptInDefaultExclude(),
fmt.Sprintf(`
resource "aws_opsworks_stack" "test" {
name = %[1]q
region = %[2]q
service_role_arn = aws_iam_role.opsworks_service.arn
default_instance_profile_arn = aws_iam_instance_profile.opsworks_instance.arn
use_opsworks_security_groups = false
default_availability_zone = data.aws_availability_zones.available.names[1]
}

data "aws_vpc" "default" {
default = true
}
`, rName, acctest.Region()))
}

func testAccStackConfig_tags1(rName, tagKey1, tagValue1 string) string {
return acctest.ConfigCompose(testAccStackConfig_baseVPC(rName), fmt.Sprintf(`
resource "aws_opsworks_stack" "test" {
Expand Down
27 changes: 12 additions & 15 deletions website/docs/r/opsworks_stack.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,29 @@ The following arguments are supported:
* `name` - (Required) The name of the stack.
* `region` - (Required) The name of the region where the stack will exist.
* `service_role_arn` - (Required) The ARN of an IAM role that the OpsWorks service will act as.
* `default_instance_profile_arn` - (Required) The ARN of an IAM Instance Profile that created instances
will have by default.
* `default_instance_profile_arn` - (Required) The ARN of an IAM Instance Profile that created instances will have by default.
* `agent_version` - (Optional) If set to `"LATEST"`, OpsWorks will automatically install the latest version.
* `berkshelf_version` - (Optional) If `manage_berkshelf` is enabled, the version of Berkshelf to use.
* `color` - (Optional) Color to paint next to the stack's resources in the OpsWorks console.
* `default_availability_zone` - (Optional) Name of the availability zone where instances will be created
by default. This is required unless you set `vpc_id`.
* `configuration_manager_name` - (Optional) Name of the configuration manager to use. Defaults to "Chef".
* `configuration_manager_version` - (Optional) Version of the configuration manager to use. Defaults to "11.4".
* `custom_cookbooks_source` - (Optional) When `use_custom_cookbooks` is set, provide this sub-object as
described below.
* `custom_cookbooks_source` - (Optional) When `use_custom_cookbooks` is set, provide this sub-object as described below.
* `custom_json` - (Optional) User defined JSON passed to "Chef". Use a "here doc" for multiline JSON.
* `default_availability_zone` - (Optional) Name of the availability zone where instances will be created by default.
Cannot be set when `vpc_id` is set.
* `default_os` - (Optional) Name of OS that will be installed on instances by default.
* `default_root_device_type` - (Optional) Name of the type of root device instances will have by default.
* `default_ssh_key_name` - (Optional) Name of the SSH keypair that instances will have by default.
* `default_subnet_id` - (Optional) Id of the subnet in which instances will be created by default. Mandatory
if `vpc_id` is set, and forbidden if it isn't.
* `hostname_theme` - (Optional) Keyword representing the naming scheme that will be used for instance hostnames
within this stack.
* `default_subnet_id` - (Optional) ID of the subnet in which instances will be created by default.
Required if `vpc_id` is set to a VPC other than the default VPC, and forbidden if it isn't.
* `hostname_theme` - (Optional) Keyword representing the naming scheme that will be used for instance hostnames within this stack.
* `manage_berkshelf` - (Optional) Boolean value controlling whether Opsworks will run Berkshelf for this stack.
* `tags` - (Optional) A map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
* `use_custom_cookbooks` - (Optional) Boolean value controlling whether the custom cookbook settings are
enabled.
* `use_opsworks_security_groups` - (Optional) Boolean value controlling whether the standard OpsWorks
security groups apply to created instances.
* `tags` - (Optional) A map of tags to assign to the resource.
If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
* `use_custom_cookbooks` - (Optional) Boolean value controlling whether the custom cookbook settings are enabled.
* `use_opsworks_security_groups` - (Optional) Boolean value controlling whether the standard OpsWorks security groups apply to created instances.
* `vpc_id` - (Optional) ID of the VPC that this stack belongs to.
Defaults to the region's default VPC.
* `custom_json` - (Optional) Custom JSON attributes to apply to the entire stack.

The `custom_cookbooks_source` block supports the following arguments:
Expand Down