opentofu/builtin/providers/aws/resource_aws_opsworks_stack_test.go
Martin Atkins e41616198f Don't read back opsworks stack cookbooks source password (#6203)
As with several other sensitive values in Opsworks, the API returns a
placeholder value rather than a nil. To avoid writing the placeholder
value into the state we just skip updating the password on read, letting
whatever value was in the state persist.

This means that Terraform can't detect configuration drift where someone
has changed the password via some other means, but Terraform will still
be able to recognize changes to the password made within Terraform itself
due to the "last-written" value in the state.

This fixes #6192.
2016-04-16 22:56:36 +01:00

595 lines
14 KiB
Go

package aws
import (
"fmt"
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/opsworks"
)
///////////////////////////////
//// Tests for the No-VPC case
///////////////////////////////
func TestAccAWSOpsworksStackNoVpc(t *testing.T) {
stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAwsOpsworksStackConfigNoVpcCreate(stackName),
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate("us-east-1c", stackName),
},
// resource.TestStep{
// Config: testAccAWSOpsworksStackConfigNoVpcUpdate(stackName),
// Check: testAccAwsOpsworksStackCheckResourceAttrsUpdate("us-east-1c", stackName),
// },
},
})
}
func TestAccAWSOpsworksStackVpc(t *testing.T) {
stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAwsOpsworksStackConfigVpcCreate(stackName),
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate("us-west-2a", stackName),
},
resource.TestStep{
Config: testAccAWSOpsworksStackConfigVpcUpdate(stackName),
Check: resource.ComposeTestCheckFunc(
testAccAwsOpsworksStackCheckResourceAttrsUpdate("us-west-2a", stackName),
testAccAwsOpsworksCheckVpc,
),
},
},
})
}
////////////////////////////
//// Checkers and Utilities
////////////////////////////
func testAccAwsOpsworksStackCheckResourceAttrsCreate(zone, stackName string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"name",
stackName,
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"default_availability_zone",
zone,
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"default_os",
"Amazon Linux 2014.09",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"default_root_device_type",
"ebs",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"custom_json",
`{"key": "value"}`,
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"configuration_manager_version",
"11.10",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"use_opsworks_security_groups",
"false",
),
)
}
func testAccAwsOpsworksStackCheckResourceAttrsUpdate(zone, stackName string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"name",
stackName,
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"default_availability_zone",
zone,
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"default_os",
"Amazon Linux 2014.09",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"default_root_device_type",
"ebs",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"custom_json",
`{"key": "value"}`,
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"configuration_manager_version",
"11.10",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"use_opsworks_security_groups",
"false",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"use_custom_cookbooks",
"true",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"manage_berkshelf",
"true",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"custom_cookbooks_source.0.type",
"git",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"custom_cookbooks_source.0.revision",
"master",
),
resource.TestCheckResourceAttr(
"aws_opsworks_stack.tf-acc",
"custom_cookbooks_source.0.url",
"https://github.com/aws/opsworks-example-cookbooks.git",
),
)
}
func testAccAwsOpsworksCheckVpc(s *terraform.State) error {
rs, ok := s.RootModule().Resources["aws_opsworks_stack.tf-acc"]
if !ok {
return fmt.Errorf("Not found: %s", "aws_opsworks_stack.tf-acc")
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
p := rs.Primary
opsworksconn := testAccProvider.Meta().(*AWSClient).opsworksconn
describeOpts := &opsworks.DescribeStacksInput{
StackIds: []*string{aws.String(p.ID)},
}
resp, err := opsworksconn.DescribeStacks(describeOpts)
if err != nil {
return err
}
if len(resp.Stacks) == 0 {
return fmt.Errorf("No stack %s not found", p.ID)
}
if p.Attributes["vpc_id"] != *resp.Stacks[0].VpcId {
return fmt.Errorf("VPCID Got %s, expected %s", *resp.Stacks[0].VpcId, p.Attributes["vpc_id"])
}
if p.Attributes["default_subnet_id"] != *resp.Stacks[0].DefaultSubnetId {
return fmt.Errorf("VPCID Got %s, expected %s", *resp.Stacks[0].DefaultSubnetId, p.Attributes["default_subnet_id"])
}
return nil
}
func testAccCheckAwsOpsworksStackDestroy(s *terraform.State) error {
opsworksconn := testAccProvider.Meta().(*AWSClient).opsworksconn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_opsworks_stack" {
continue
}
req := &opsworks.DescribeStacksInput{
StackIds: []*string{
aws.String(rs.Primary.ID),
},
}
_, err := opsworksconn.DescribeStacks(req)
if err != nil {
if awserr, ok := err.(awserr.Error); ok {
if awserr.Code() == "ResourceNotFoundException" {
// not found, all good
return nil
}
}
return err
}
}
return fmt.Errorf("Fall through error for OpsWorks stack test")
}
//////////////////////////////////////////////////
//// Helper configs for the necessary IAM objects
//////////////////////////////////////////////////
func testAccAwsOpsworksStackConfigNoVpcCreate(name string) string {
return fmt.Sprintf(`
resource "aws_opsworks_stack" "tf-acc" {
name = "%s"
region = "us-east-1"
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
default_availability_zone = "us-east-1c"
default_os = "Amazon Linux 2014.09"
default_root_device_type = "ebs"
custom_json = "{\"key\": \"value\"}"
configuration_manager_version = "11.10"
use_opsworks_security_groups = false
}
resource "aws_iam_role" "opsworks_service" {
name = "%s_opsworks_service"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "opsworks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_role_policy" "opsworks_service" {
name = "%s_opsworks_service"
role = "${aws_iam_role.opsworks_service.id}"
policy = <<EOT
{
"Statement": [
{
"Action": [
"ec2:*",
"iam:PassRole",
"cloudwatch:GetMetricStatistics",
"elasticloadbalancing:*",
"rds:*"
],
"Effect": "Allow",
"Resource": ["*"]
}
]
}
EOT
}
resource "aws_iam_role" "opsworks_instance" {
name = "%s_opsworks_instance"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_instance_profile" "opsworks_instance" {
name = "%s_opsworks_instance"
roles = ["${aws_iam_role.opsworks_instance.name}"]
}`, name, name, name, name, name)
}
func testAccAWSOpsworksStackConfigNoVpcUpdate(name string) string {
return fmt.Sprintf(`
resource "aws_opsworks_stack" "tf-acc" {
name = "%s"
region = "us-east-1"
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
default_availability_zone = "us-east-1c"
default_os = "Amazon Linux 2014.09"
default_root_device_type = "ebs"
custom_json = "{\"key\": \"value\"}"
configuration_manager_version = "11.10"
use_opsworks_security_groups = false
use_custom_cookbooks = true
manage_berkshelf = true
custom_cookbooks_source {
type = "git"
revision = "master"
url = "https://github.com/aws/opsworks-example-cookbooks.git"
username = "example"
password = "example"
}
resource "aws_iam_role" "opsworks_service" {
name = "%s_opsworks_service"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "opsworks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_role_policy" "opsworks_service" {
name = "%s_opsworks_service"
role = "${aws_iam_role.opsworks_service.id}"
policy = <<EOT
{
"Statement": [
{
"Action": [
"ec2:*",
"iam:PassRole",
"cloudwatch:GetMetricStatistics",
"elasticloadbalancing:*",
"rds:*"
],
"Effect": "Allow",
"Resource": ["*"]
}
]
}
EOT
}
resource "aws_iam_role" "opsworks_instance" {
name = "%s_opsworks_instance"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_instance_profile" "opsworks_instance" {
name = "%s_opsworks_instance"
roles = ["${aws_iam_role.opsworks_instance.name}"]
}
`, name, name, name, name, name)
}
////////////////////////////
//// Tests for the VPC case
////////////////////////////
func testAccAwsOpsworksStackConfigVpcCreate(name string) string {
return fmt.Sprintf(`
resource "aws_vpc" "tf-acc" {
cidr_block = "10.3.5.0/24"
}
resource "aws_subnet" "tf-acc" {
vpc_id = "${aws_vpc.tf-acc.id}"
cidr_block = "${aws_vpc.tf-acc.cidr_block}"
availability_zone = "us-west-2a"
}
resource "aws_opsworks_stack" "tf-acc" {
name = "%s"
region = "us-west-2"
vpc_id = "${aws_vpc.tf-acc.id}"
default_subnet_id = "${aws_subnet.tf-acc.id}"
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
default_os = "Amazon Linux 2014.09"
default_root_device_type = "ebs"
custom_json = "{\"key\": \"value\"}"
configuration_manager_version = "11.10"
use_opsworks_security_groups = false
}
resource "aws_iam_role" "opsworks_service" {
name = "%s_opsworks_service"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "opsworks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_role_policy" "opsworks_service" {
name = "%s_opsworks_service"
role = "${aws_iam_role.opsworks_service.id}"
policy = <<EOT
{
"Statement": [
{
"Action": [
"ec2:*",
"iam:PassRole",
"cloudwatch:GetMetricStatistics",
"elasticloadbalancing:*",
"rds:*"
],
"Effect": "Allow",
"Resource": ["*"]
}
]
}
EOT
}
resource "aws_iam_role" "opsworks_instance" {
name = "%s_opsworks_instance"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_instance_profile" "opsworks_instance" {
name = "%s_opsworks_instance"
roles = ["${aws_iam_role.opsworks_instance.name}"]
}
`, name, name, name, name, name)
}
func testAccAWSOpsworksStackConfigVpcUpdate(name string) string {
return fmt.Sprintf(`
resource "aws_vpc" "tf-acc" {
cidr_block = "10.3.5.0/24"
}
resource "aws_subnet" "tf-acc" {
vpc_id = "${aws_vpc.tf-acc.id}"
cidr_block = "${aws_vpc.tf-acc.cidr_block}"
availability_zone = "us-west-2a"
}
resource "aws_opsworks_stack" "tf-acc" {
name = "%s"
region = "us-west-2"
vpc_id = "${aws_vpc.tf-acc.id}"
default_subnet_id = "${aws_subnet.tf-acc.id}"
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
default_os = "Amazon Linux 2014.09"
default_root_device_type = "ebs"
custom_json = "{\"key\": \"value\"}"
configuration_manager_version = "11.10"
use_opsworks_security_groups = false
use_custom_cookbooks = true
manage_berkshelf = true
custom_cookbooks_source {
type = "git"
revision = "master"
url = "https://github.com/aws/opsworks-example-cookbooks.git"
}
}
resource "aws_iam_role" "opsworks_service" {
name = "%s_opsworks_service"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "opsworks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_role_policy" "opsworks_service" {
name = "%s_opsworks_service"
role = "${aws_iam_role.opsworks_service.id}"
policy = <<EOT
{
"Statement": [
{
"Action": [
"ec2:*",
"iam:PassRole",
"cloudwatch:GetMetricStatistics",
"elasticloadbalancing:*",
"rds:*"
],
"Effect": "Allow",
"Resource": ["*"]
}
]
}
EOT
}
resource "aws_iam_role" "opsworks_instance" {
name = "%s_opsworks_instance"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_instance_profile" "opsworks_instance" {
name = "%s_opsworks_instance"
roles = ["${aws_iam_role.opsworks_instance.name}"]
}
`, name, name, name, name, name)
}