AWS Opsworks tests bring their own IAM objects.
Previously we assumed the existence of some default objects that most Opsworks users have because the Opsworks console creates them by default when a new stack is created. However, that meant that these tests wouldn't work correctly for anyone who either had never used Opsworks via the UI or who had never accepted the default of having the console create some predefined IAM objects to use. It may also have led to some weird failures if a particular user had customized the settings for these default objects. Now the tests create suitable IAM roles, a policy and an instance profile and use these when creating Opsworks stacks, avoiding any dependency on any pre-existing objects. This fixes #3998.
This commit is contained in:
parent
cf87ede5dd
commit
11190144f0
|
@ -12,16 +12,13 @@ import (
|
||||||
// and `aws-opsworks-service-role`.
|
// and `aws-opsworks-service-role`.
|
||||||
|
|
||||||
func TestAccAwsOpsworksCustomLayer(t *testing.T) {
|
func TestAccAwsOpsworksCustomLayer(t *testing.T) {
|
||||||
opsiam := testAccAwsOpsworksStackIam{}
|
|
||||||
testAccAwsOpsworksStackPopulateIam(t, &opsiam)
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
Providers: testAccProviders,
|
Providers: testAccProviders,
|
||||||
CheckDestroy: testAccCheckAwsOpsworksCustomLayerDestroy,
|
CheckDestroy: testAccCheckAwsOpsworksCustomLayerDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: fmt.Sprintf(testAccAwsOpsworksCustomLayerConfigCreate, opsiam.ServiceRoleArn, opsiam.InstanceProfileArn),
|
Config: testAccAwsOpsworksCustomLayerConfigCreate,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(
|
resource.TestCheckResourceAttr(
|
||||||
"aws_opsworks_custom_layer.tf-acc", "name", "tf-ops-acc-custom-layer",
|
"aws_opsworks_custom_layer.tf-acc", "name", "tf-ops-acc-custom-layer",
|
||||||
|
@ -68,7 +65,7 @@ func TestAccAwsOpsworksCustomLayer(t *testing.T) {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: fmt.Sprintf(testAccAwsOpsworksCustomLayerConfigUpdate, opsiam.ServiceRoleArn, opsiam.InstanceProfileArn),
|
Config: testAccAwsOpsworksCustomLayerConfigUpdate,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(
|
resource.TestCheckResourceAttr(
|
||||||
"aws_opsworks_custom_layer.tf-acc", "name", "tf-ops-acc-custom-layer",
|
"aws_opsworks_custom_layer.tf-acc", "name", "tf-ops-acc-custom-layer",
|
||||||
|
|
|
@ -8,23 +8,91 @@ import (
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/service/iam"
|
|
||||||
"github.com/aws/aws-sdk-go/service/opsworks"
|
"github.com/aws/aws-sdk-go/service/opsworks"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These tests assume the existence of predefined Opsworks IAM roles named `aws-opsworks-ec2-role`
|
//////////////////////////////////////////////////
|
||||||
// and `aws-opsworks-service-role`.
|
//// Helper configs for the necessary IAM objects
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var testAccAwsOpsworksStackIamConfig = `
|
||||||
|
resource "aws_iam_role" "opsworks_service" {
|
||||||
|
name = "terraform_testacc_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 = "terraform_testacc_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 = "terraform_testacc_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 = "terraform_testacc_opsworks_instance"
|
||||||
|
roles = ["${aws_iam_role.opsworks_instance.name}"]
|
||||||
|
}
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
//// Tests for the No-VPC case
|
//// Tests for the No-VPC case
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
var testAccAwsOpsworksStackConfigNoVpcCreate = `
|
var testAccAwsOpsworksStackConfigNoVpcCreate = testAccAwsOpsworksStackIamConfig + `
|
||||||
resource "aws_opsworks_stack" "tf-acc" {
|
resource "aws_opsworks_stack" "tf-acc" {
|
||||||
name = "tf-opsworks-acc"
|
name = "tf-opsworks-acc"
|
||||||
region = "us-west-2"
|
region = "us-west-2"
|
||||||
service_role_arn = "%s"
|
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
|
||||||
default_instance_profile_arn = "%s"
|
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
|
||||||
default_availability_zone = "us-west-2a"
|
default_availability_zone = "us-west-2a"
|
||||||
default_os = "Amazon Linux 2014.09"
|
default_os = "Amazon Linux 2014.09"
|
||||||
default_root_device_type = "ebs"
|
default_root_device_type = "ebs"
|
||||||
|
@ -33,12 +101,12 @@ resource "aws_opsworks_stack" "tf-acc" {
|
||||||
use_opsworks_security_groups = false
|
use_opsworks_security_groups = false
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
var testAccAWSOpsworksStackConfigNoVpcUpdate = `
|
var testAccAWSOpsworksStackConfigNoVpcUpdate = testAccAwsOpsworksStackIamConfig + `
|
||||||
resource "aws_opsworks_stack" "tf-acc" {
|
resource "aws_opsworks_stack" "tf-acc" {
|
||||||
name = "tf-opsworks-acc"
|
name = "tf-opsworks-acc"
|
||||||
region = "us-west-2"
|
region = "us-west-2"
|
||||||
service_role_arn = "%s"
|
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
|
||||||
default_instance_profile_arn = "%s"
|
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
|
||||||
default_availability_zone = "us-west-2a"
|
default_availability_zone = "us-west-2a"
|
||||||
default_os = "Amazon Linux 2014.09"
|
default_os = "Amazon Linux 2014.09"
|
||||||
default_root_device_type = "ebs"
|
default_root_device_type = "ebs"
|
||||||
|
@ -56,20 +124,17 @@ resource "aws_opsworks_stack" "tf-acc" {
|
||||||
`
|
`
|
||||||
|
|
||||||
func TestAccAwsOpsworksStackNoVpc(t *testing.T) {
|
func TestAccAwsOpsworksStackNoVpc(t *testing.T) {
|
||||||
opsiam := testAccAwsOpsworksStackIam{}
|
|
||||||
testAccAwsOpsworksStackPopulateIam(t, &opsiam)
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
Providers: testAccProviders,
|
Providers: testAccProviders,
|
||||||
CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
|
CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: fmt.Sprintf(testAccAwsOpsworksStackConfigNoVpcCreate, opsiam.ServiceRoleArn, opsiam.InstanceProfileArn),
|
Config: testAccAwsOpsworksStackConfigNoVpcCreate,
|
||||||
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate,
|
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate,
|
||||||
},
|
},
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: fmt.Sprintf(testAccAWSOpsworksStackConfigNoVpcUpdate, opsiam.ServiceRoleArn, opsiam.InstanceProfileArn),
|
Config: testAccAWSOpsworksStackConfigNoVpcUpdate,
|
||||||
Check: testAccAwsOpsworksStackCheckResourceAttrsUpdate,
|
Check: testAccAwsOpsworksStackCheckResourceAttrsUpdate,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -80,7 +145,7 @@ func TestAccAwsOpsworksStackNoVpc(t *testing.T) {
|
||||||
//// Tests for the VPC case
|
//// Tests for the VPC case
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
||||||
var testAccAwsOpsworksStackConfigVpcCreate = `
|
var testAccAwsOpsworksStackConfigVpcCreate = testAccAwsOpsworksStackIamConfig + `
|
||||||
resource "aws_vpc" "tf-acc" {
|
resource "aws_vpc" "tf-acc" {
|
||||||
cidr_block = "10.3.5.0/24"
|
cidr_block = "10.3.5.0/24"
|
||||||
}
|
}
|
||||||
|
@ -94,8 +159,8 @@ resource "aws_opsworks_stack" "tf-acc" {
|
||||||
region = "us-west-2"
|
region = "us-west-2"
|
||||||
vpc_id = "${aws_vpc.tf-acc.id}"
|
vpc_id = "${aws_vpc.tf-acc.id}"
|
||||||
default_subnet_id = "${aws_subnet.tf-acc.id}"
|
default_subnet_id = "${aws_subnet.tf-acc.id}"
|
||||||
service_role_arn = "%s"
|
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
|
||||||
default_instance_profile_arn = "%s"
|
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
|
||||||
default_os = "Amazon Linux 2014.09"
|
default_os = "Amazon Linux 2014.09"
|
||||||
default_root_device_type = "ebs"
|
default_root_device_type = "ebs"
|
||||||
custom_json = "{\"key\": \"value\"}"
|
custom_json = "{\"key\": \"value\"}"
|
||||||
|
@ -104,7 +169,7 @@ resource "aws_opsworks_stack" "tf-acc" {
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
var testAccAWSOpsworksStackConfigVpcUpdate = `
|
var testAccAWSOpsworksStackConfigVpcUpdate = testAccAwsOpsworksStackIamConfig + `
|
||||||
resource "aws_vpc" "tf-acc" {
|
resource "aws_vpc" "tf-acc" {
|
||||||
cidr_block = "10.3.5.0/24"
|
cidr_block = "10.3.5.0/24"
|
||||||
}
|
}
|
||||||
|
@ -118,8 +183,8 @@ resource "aws_opsworks_stack" "tf-acc" {
|
||||||
region = "us-west-2"
|
region = "us-west-2"
|
||||||
vpc_id = "${aws_vpc.tf-acc.id}"
|
vpc_id = "${aws_vpc.tf-acc.id}"
|
||||||
default_subnet_id = "${aws_subnet.tf-acc.id}"
|
default_subnet_id = "${aws_subnet.tf-acc.id}"
|
||||||
service_role_arn = "%s"
|
service_role_arn = "${aws_iam_role.opsworks_service.arn}"
|
||||||
default_instance_profile_arn = "%s"
|
default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
|
||||||
default_os = "Amazon Linux 2014.09"
|
default_os = "Amazon Linux 2014.09"
|
||||||
default_root_device_type = "ebs"
|
default_root_device_type = "ebs"
|
||||||
custom_json = "{\"key\": \"value\"}"
|
custom_json = "{\"key\": \"value\"}"
|
||||||
|
@ -136,20 +201,17 @@ resource "aws_opsworks_stack" "tf-acc" {
|
||||||
`
|
`
|
||||||
|
|
||||||
func TestAccAwsOpsworksStackVpc(t *testing.T) {
|
func TestAccAwsOpsworksStackVpc(t *testing.T) {
|
||||||
opsiam := testAccAwsOpsworksStackIam{}
|
|
||||||
testAccAwsOpsworksStackPopulateIam(t, &opsiam)
|
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
Providers: testAccProviders,
|
Providers: testAccProviders,
|
||||||
CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
|
CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
|
||||||
Steps: []resource.TestStep{
|
Steps: []resource.TestStep{
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: fmt.Sprintf(testAccAwsOpsworksStackConfigVpcCreate, opsiam.ServiceRoleArn, opsiam.InstanceProfileArn),
|
Config: testAccAwsOpsworksStackConfigVpcCreate,
|
||||||
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate,
|
Check: testAccAwsOpsworksStackCheckResourceAttrsCreate,
|
||||||
},
|
},
|
||||||
resource.TestStep{
|
resource.TestStep{
|
||||||
Config: fmt.Sprintf(testAccAWSOpsworksStackConfigVpcUpdate, opsiam.ServiceRoleArn, opsiam.InstanceProfileArn),
|
Config: testAccAWSOpsworksStackConfigVpcUpdate,
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
testAccAwsOpsworksStackCheckResourceAttrsUpdate,
|
testAccAwsOpsworksStackCheckResourceAttrsUpdate,
|
||||||
testAccAwsOpsworksCheckVpc,
|
testAccAwsOpsworksCheckVpc,
|
||||||
|
@ -302,53 +364,3 @@ func testAccCheckAwsOpsworksStackDestroy(s *terraform.State) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Holds the two IAM object ARNs used in stack objects we'll create.
|
|
||||||
type testAccAwsOpsworksStackIam struct {
|
|
||||||
ServiceRoleArn string
|
|
||||||
InstanceProfileArn string
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccAwsOpsworksStackPopulateIam(t *testing.T, opsiam *testAccAwsOpsworksStackIam) {
|
|
||||||
resource.Test(t, resource.TestCase{
|
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
|
||||||
Providers: testAccProviders,
|
|
||||||
Steps: []resource.TestStep{
|
|
||||||
resource.TestStep{
|
|
||||||
Config: testAccInstanceConfig_pre, // noop
|
|
||||||
Check: testAccCheckAwsOpsworksEnsureIam(t, opsiam),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckAwsOpsworksEnsureIam(t *testing.T, opsiam *testAccAwsOpsworksStackIam) func(*terraform.State) error {
|
|
||||||
return func(_ *terraform.State) error {
|
|
||||||
iamconn := testAccProvider.Meta().(*AWSClient).iamconn
|
|
||||||
|
|
||||||
serviceRoleOpts := &iam.GetRoleInput{
|
|
||||||
RoleName: aws.String("aws-opsworks-service-role"),
|
|
||||||
}
|
|
||||||
respServiceRole, err := iamconn.GetRole(serviceRoleOpts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceProfileOpts := &iam.GetInstanceProfileInput{
|
|
||||||
InstanceProfileName: aws.String("aws-opsworks-ec2-role"),
|
|
||||||
}
|
|
||||||
respInstanceProfile, err := iamconn.GetInstanceProfile(instanceProfileOpts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
opsiam.ServiceRoleArn = *respServiceRole.Role.Arn
|
|
||||||
opsiam.InstanceProfileArn = *respInstanceProfile.InstanceProfile.Arn
|
|
||||||
|
|
||||||
t.Logf("[DEBUG] ServiceRoleARN for OpsWorks: %s", opsiam.ServiceRoleArn)
|
|
||||||
t.Logf("[DEBUG] Instance Profile ARN for OpsWorks: %s", opsiam.InstanceProfileArn)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue