github.com/sixgill/terraform@v0.9.0-beta2.0.20170316214032-033f6226ae50/builtin/providers/aws/resource_aws_opsworks_stack_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/helper/acctest"
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/terraform"
    10  
    11  	"github.com/aws/aws-sdk-go/aws"
    12  	"github.com/aws/aws-sdk-go/aws/awserr"
    13  	"github.com/aws/aws-sdk-go/service/opsworks"
    14  )
    15  
    16  ///////////////////////////////
    17  //// Tests for the No-VPC case
    18  ///////////////////////////////
    19  
    20  func TestAccAWSOpsworksStackNoVpc(t *testing.T) {
    21  	stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt())
    22  	var opsstack opsworks.Stack
    23  	resource.Test(t, resource.TestCase{
    24  		PreCheck:     func() { testAccPreCheck(t) },
    25  		Providers:    testAccProviders,
    26  		CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
    27  		Steps: []resource.TestStep{
    28  			{
    29  				Config: testAccAwsOpsworksStackConfigNoVpcCreate(stackName),
    30  				Check: resource.ComposeTestCheckFunc(
    31  					testAccCheckAWSOpsworksStackExists(
    32  						"aws_opsworks_stack.tf-acc", false, &opsstack),
    33  					testAccCheckAWSOpsworksCreateStackAttributes(
    34  						&opsstack, "us-east-1a", stackName),
    35  					testAccAwsOpsworksStackCheckResourceAttrsCreate(
    36  						"us-east-1a", stackName),
    37  				),
    38  			},
    39  		},
    40  	})
    41  }
    42  
    43  func TestAccAWSOpsworksStackVpc(t *testing.T) {
    44  	stackName := fmt.Sprintf("tf-opsworks-acc-%d", acctest.RandInt())
    45  	var opsstack opsworks.Stack
    46  	resource.Test(t, resource.TestCase{
    47  		PreCheck:     func() { testAccPreCheck(t) },
    48  		Providers:    testAccProviders,
    49  		CheckDestroy: testAccCheckAwsOpsworksStackDestroy,
    50  		Steps: []resource.TestStep{
    51  			{
    52  				Config: testAccAwsOpsworksStackConfigVpcCreate(stackName),
    53  				Check: resource.ComposeTestCheckFunc(
    54  					testAccCheckAWSOpsworksStackExists(
    55  						"aws_opsworks_stack.tf-acc", true, &opsstack),
    56  					testAccCheckAWSOpsworksCreateStackAttributes(
    57  						&opsstack, "us-west-2a", stackName),
    58  					testAccAwsOpsworksStackCheckResourceAttrsCreate(
    59  						"us-west-2a", stackName),
    60  				),
    61  			},
    62  			{
    63  				Config: testAccAWSOpsworksStackConfigVpcUpdate(stackName),
    64  				Check: resource.ComposeTestCheckFunc(
    65  					testAccCheckAWSOpsworksStackExists(
    66  						"aws_opsworks_stack.tf-acc", true, &opsstack),
    67  					testAccCheckAWSOpsworksUpdateStackAttributes(
    68  						&opsstack, "us-west-2a", stackName),
    69  					testAccAwsOpsworksStackCheckResourceAttrsUpdate(
    70  						"us-west-2a", stackName),
    71  				),
    72  			},
    73  		},
    74  	})
    75  }
    76  
    77  ////////////////////////////
    78  //// Checkers and Utilities
    79  ////////////////////////////
    80  
    81  func testAccAwsOpsworksStackCheckResourceAttrsCreate(zone, stackName string) resource.TestCheckFunc {
    82  	return resource.ComposeTestCheckFunc(
    83  		resource.TestCheckResourceAttr(
    84  			"aws_opsworks_stack.tf-acc",
    85  			"name",
    86  			stackName,
    87  		),
    88  		resource.TestCheckResourceAttr(
    89  			"aws_opsworks_stack.tf-acc",
    90  			"default_availability_zone",
    91  			zone,
    92  		),
    93  		resource.TestCheckResourceAttr(
    94  			"aws_opsworks_stack.tf-acc",
    95  			"default_os",
    96  			"Amazon Linux 2016.09",
    97  		),
    98  		resource.TestCheckResourceAttr(
    99  			"aws_opsworks_stack.tf-acc",
   100  			"default_root_device_type",
   101  			"ebs",
   102  		),
   103  		resource.TestCheckResourceAttr(
   104  			"aws_opsworks_stack.tf-acc",
   105  			"custom_json",
   106  			`{"key": "value"}`,
   107  		),
   108  		resource.TestCheckResourceAttr(
   109  			"aws_opsworks_stack.tf-acc",
   110  			"configuration_manager_version",
   111  			"11.10",
   112  		),
   113  		resource.TestCheckResourceAttr(
   114  			"aws_opsworks_stack.tf-acc",
   115  			"use_opsworks_security_groups",
   116  			"false",
   117  		),
   118  	)
   119  }
   120  
   121  func testAccAwsOpsworksStackCheckResourceAttrsUpdate(zone, stackName string) resource.TestCheckFunc {
   122  	return resource.ComposeTestCheckFunc(
   123  		resource.TestCheckResourceAttr(
   124  			"aws_opsworks_stack.tf-acc",
   125  			"name",
   126  			stackName,
   127  		),
   128  		resource.TestCheckResourceAttr(
   129  			"aws_opsworks_stack.tf-acc",
   130  			"default_availability_zone",
   131  			zone,
   132  		),
   133  		resource.TestCheckResourceAttr(
   134  			"aws_opsworks_stack.tf-acc",
   135  			"default_os",
   136  			"Amazon Linux 2015.09",
   137  		),
   138  		resource.TestCheckResourceAttr(
   139  			"aws_opsworks_stack.tf-acc",
   140  			"default_root_device_type",
   141  			"ebs",
   142  		),
   143  		resource.TestCheckResourceAttr(
   144  			"aws_opsworks_stack.tf-acc",
   145  			"custom_json",
   146  			`{"key": "value"}`,
   147  		),
   148  		resource.TestCheckResourceAttr(
   149  			"aws_opsworks_stack.tf-acc",
   150  			"configuration_manager_version",
   151  			"11.10",
   152  		),
   153  		resource.TestCheckResourceAttr(
   154  			"aws_opsworks_stack.tf-acc",
   155  			"use_opsworks_security_groups",
   156  			"false",
   157  		),
   158  		resource.TestCheckResourceAttr(
   159  			"aws_opsworks_stack.tf-acc",
   160  			"use_custom_cookbooks",
   161  			"true",
   162  		),
   163  		resource.TestCheckResourceAttr(
   164  			"aws_opsworks_stack.tf-acc",
   165  			"manage_berkshelf",
   166  			"true",
   167  		),
   168  		resource.TestCheckResourceAttr(
   169  			"aws_opsworks_stack.tf-acc",
   170  			"custom_cookbooks_source.0.type",
   171  			"git",
   172  		),
   173  		resource.TestCheckResourceAttr(
   174  			"aws_opsworks_stack.tf-acc",
   175  			"custom_cookbooks_source.0.revision",
   176  			"master",
   177  		),
   178  		resource.TestCheckResourceAttr(
   179  			"aws_opsworks_stack.tf-acc",
   180  			"custom_cookbooks_source.0.url",
   181  			"https://github.com/aws/opsworks-example-cookbooks.git",
   182  		),
   183  	)
   184  }
   185  
   186  func testAccCheckAWSOpsworksStackExists(
   187  	n string, vpc bool, opsstack *opsworks.Stack) resource.TestCheckFunc {
   188  	return func(s *terraform.State) error {
   189  		rs, ok := s.RootModule().Resources[n]
   190  		if !ok {
   191  			return fmt.Errorf("Not found: %s", n)
   192  		}
   193  
   194  		if rs.Primary.ID == "" {
   195  			return fmt.Errorf("No ID is set")
   196  		}
   197  
   198  		conn := testAccProvider.Meta().(*AWSClient).opsworksconn
   199  
   200  		params := &opsworks.DescribeStacksInput{
   201  			StackIds: []*string{aws.String(rs.Primary.ID)},
   202  		}
   203  		resp, err := conn.DescribeStacks(params)
   204  
   205  		if err != nil {
   206  			return err
   207  		}
   208  
   209  		if v := len(resp.Stacks); v != 1 {
   210  			return fmt.Errorf("Expected 1 response returned, got %d", v)
   211  		}
   212  
   213  		*opsstack = *resp.Stacks[0]
   214  
   215  		if vpc {
   216  			if rs.Primary.Attributes["vpc_id"] != *opsstack.VpcId {
   217  				return fmt.Errorf("VPCID Got %s, expected %s", *opsstack.VpcId, rs.Primary.Attributes["vpc_id"])
   218  			}
   219  			if rs.Primary.Attributes["default_subnet_id"] != *opsstack.DefaultSubnetId {
   220  				return fmt.Errorf("Default subnet Id Got %s, expected %s", *opsstack.DefaultSubnetId, rs.Primary.Attributes["default_subnet_id"])
   221  			}
   222  		}
   223  
   224  		return nil
   225  	}
   226  }
   227  
   228  func testAccCheckAWSOpsworksCreateStackAttributes(
   229  	opsstack *opsworks.Stack, zone, stackName string) resource.TestCheckFunc {
   230  	return func(s *terraform.State) error {
   231  		if *opsstack.Name != stackName {
   232  			return fmt.Errorf("Unnexpected stackName: %s", *opsstack.Name)
   233  		}
   234  
   235  		if *opsstack.DefaultAvailabilityZone != zone {
   236  			return fmt.Errorf("Unnexpected DefaultAvailabilityZone: %s", *opsstack.DefaultAvailabilityZone)
   237  		}
   238  
   239  		if *opsstack.DefaultOs != "Amazon Linux 2016.09" {
   240  			return fmt.Errorf("Unnexpected stackName: %s", *opsstack.DefaultOs)
   241  		}
   242  
   243  		if *opsstack.DefaultRootDeviceType != "ebs" {
   244  			return fmt.Errorf("Unnexpected DefaultRootDeviceType: %s", *opsstack.DefaultRootDeviceType)
   245  		}
   246  
   247  		if *opsstack.CustomJson != `{"key": "value"}` {
   248  			return fmt.Errorf("Unnexpected CustomJson: %s", *opsstack.CustomJson)
   249  		}
   250  
   251  		if *opsstack.ConfigurationManager.Version != "11.10" {
   252  			return fmt.Errorf("Unnexpected Version: %s", *opsstack.ConfigurationManager.Version)
   253  		}
   254  
   255  		if *opsstack.UseOpsworksSecurityGroups {
   256  			return fmt.Errorf("Unnexpected UseOpsworksSecurityGroups: %t", *opsstack.UseOpsworksSecurityGroups)
   257  		}
   258  
   259  		return nil
   260  	}
   261  }
   262  
   263  func testAccCheckAWSOpsworksUpdateStackAttributes(
   264  	opsstack *opsworks.Stack, zone, stackName string) resource.TestCheckFunc {
   265  	return func(s *terraform.State) error {
   266  		if *opsstack.Name != stackName {
   267  			return fmt.Errorf("Unnexpected stackName: %s", *opsstack.Name)
   268  		}
   269  
   270  		if *opsstack.DefaultAvailabilityZone != zone {
   271  			return fmt.Errorf("Unnexpected DefaultAvailabilityZone: %s", *opsstack.DefaultAvailabilityZone)
   272  		}
   273  
   274  		if *opsstack.DefaultOs != "Amazon Linux 2015.09" {
   275  			return fmt.Errorf("Unnexpected stackName: %s", *opsstack.DefaultOs)
   276  		}
   277  
   278  		if *opsstack.DefaultRootDeviceType != "ebs" {
   279  			return fmt.Errorf("Unnexpected DefaultRootDeviceType: %s", *opsstack.DefaultRootDeviceType)
   280  		}
   281  
   282  		if *opsstack.CustomJson != `{"key": "value"}` {
   283  			return fmt.Errorf("Unnexpected CustomJson: %s", *opsstack.CustomJson)
   284  		}
   285  
   286  		if *opsstack.ConfigurationManager.Version != "11.10" {
   287  			return fmt.Errorf("Unnexpected Version: %s", *opsstack.ConfigurationManager.Version)
   288  		}
   289  
   290  		if !*opsstack.UseCustomCookbooks {
   291  			return fmt.Errorf("Unnexpected UseCustomCookbooks: %t", *opsstack.UseCustomCookbooks)
   292  		}
   293  
   294  		if !*opsstack.ChefConfiguration.ManageBerkshelf {
   295  			return fmt.Errorf("Unnexpected ManageBerkshelf: %t", *opsstack.ChefConfiguration.ManageBerkshelf)
   296  		}
   297  
   298  		if *opsstack.CustomCookbooksSource.Type != "git" {
   299  			return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Type)
   300  		}
   301  
   302  		if *opsstack.CustomCookbooksSource.Revision != "master" {
   303  			return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Revision)
   304  		}
   305  
   306  		if *opsstack.CustomCookbooksSource.Url != "https://github.com/aws/opsworks-example-cookbooks.git" {
   307  			return fmt.Errorf("Unnexpected *opsstack.CustomCookbooksSource.Type: %s", *opsstack.CustomCookbooksSource.Url)
   308  		}
   309  
   310  		return nil
   311  	}
   312  }
   313  
   314  func testAccCheckAwsOpsworksStackDestroy(s *terraform.State) error {
   315  	opsworksconn := testAccProvider.Meta().(*AWSClient).opsworksconn
   316  	for _, rs := range s.RootModule().Resources {
   317  		if rs.Type != "aws_opsworks_stack" {
   318  			continue
   319  		}
   320  
   321  		req := &opsworks.DescribeStacksInput{
   322  			StackIds: []*string{
   323  				aws.String(rs.Primary.ID),
   324  			},
   325  		}
   326  
   327  		_, err := opsworksconn.DescribeStacks(req)
   328  		if err != nil {
   329  			if awserr, ok := err.(awserr.Error); ok {
   330  				if awserr.Code() == "ResourceNotFoundException" {
   331  					// not found, all good
   332  					return nil
   333  				}
   334  			}
   335  			return err
   336  		}
   337  	}
   338  	return fmt.Errorf("Fall through error for OpsWorks stack test")
   339  }
   340  
   341  //////////////////////////////////////////////////
   342  //// Helper configs for the necessary IAM objects
   343  //////////////////////////////////////////////////
   344  
   345  func testAccAwsOpsworksStackConfigNoVpcCreate(name string) string {
   346  	return fmt.Sprintf(`
   347  provider "aws" {
   348    region = "us-east-1"
   349  }
   350  resource "aws_opsworks_stack" "tf-acc" {
   351    name = "%s"
   352    region = "us-east-1"
   353    service_role_arn = "${aws_iam_role.opsworks_service.arn}"
   354    default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
   355    default_availability_zone = "us-east-1a"
   356    default_os = "Amazon Linux 2016.09"
   357    default_root_device_type = "ebs"
   358    custom_json = "{\"key\": \"value\"}"
   359    configuration_manager_version = "11.10"
   360    use_opsworks_security_groups = false
   361  }
   362  
   363  resource "aws_iam_role" "opsworks_service" {
   364      name = "%s_opsworks_service"
   365      assume_role_policy = <<EOT
   366  {
   367    "Version": "2008-10-17",
   368    "Statement": [
   369      {
   370        "Sid": "",
   371        "Effect": "Allow",
   372        "Principal": {
   373          "Service": "opsworks.amazonaws.com"
   374        },
   375        "Action": "sts:AssumeRole"
   376      }
   377    ]
   378  }
   379  EOT
   380  }
   381  
   382  resource "aws_iam_role_policy" "opsworks_service" {
   383      name = "%s_opsworks_service"
   384      role = "${aws_iam_role.opsworks_service.id}"
   385      policy = <<EOT
   386  {
   387    "Statement": [
   388      {
   389        "Action": [
   390          "ec2:*",
   391          "iam:PassRole",
   392          "cloudwatch:GetMetricStatistics",
   393          "elasticloadbalancing:*",
   394          "rds:*"
   395        ],
   396        "Effect": "Allow",
   397        "Resource": ["*"]
   398      }
   399    ]
   400  }
   401  EOT
   402  }
   403  
   404  resource "aws_iam_role" "opsworks_instance" {
   405      name = "%s_opsworks_instance"
   406      assume_role_policy = <<EOT
   407  {
   408    "Version": "2008-10-17",
   409    "Statement": [
   410      {
   411        "Sid": "",
   412        "Effect": "Allow",
   413        "Principal": {
   414          "Service": "ec2.amazonaws.com"
   415        },
   416        "Action": "sts:AssumeRole"
   417      }
   418    ]
   419  }
   420  EOT
   421  }
   422  
   423  resource "aws_iam_instance_profile" "opsworks_instance" {
   424      name = "%s_opsworks_instance"
   425      roles = ["${aws_iam_role.opsworks_instance.name}"]
   426  }`, name, name, name, name, name)
   427  }
   428  
   429  ////////////////////////////
   430  //// Tests for the VPC case
   431  ////////////////////////////
   432  
   433  func testAccAwsOpsworksStackConfigVpcCreate(name string) string {
   434  	return fmt.Sprintf(`
   435  resource "aws_vpc" "tf-acc" {
   436    cidr_block = "10.3.5.0/24"
   437  }
   438  resource "aws_subnet" "tf-acc" {
   439    vpc_id = "${aws_vpc.tf-acc.id}"
   440    cidr_block = "${aws_vpc.tf-acc.cidr_block}"
   441    availability_zone = "us-west-2a"
   442  }
   443  resource "aws_opsworks_stack" "tf-acc" {
   444    name = "%s"
   445    region = "us-west-2"
   446    vpc_id = "${aws_vpc.tf-acc.id}"
   447    default_subnet_id = "${aws_subnet.tf-acc.id}"
   448    service_role_arn = "${aws_iam_role.opsworks_service.arn}"
   449    default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
   450    default_os = "Amazon Linux 2016.09"
   451    default_root_device_type = "ebs"
   452    custom_json = "{\"key\": \"value\"}"
   453    configuration_manager_version = "11.10"
   454    use_opsworks_security_groups = false
   455  }
   456  
   457  resource "aws_iam_role" "opsworks_service" {
   458      name = "%s_opsworks_service"
   459      assume_role_policy = <<EOT
   460  {
   461    "Version": "2008-10-17",
   462    "Statement": [
   463      {
   464        "Sid": "",
   465        "Effect": "Allow",
   466        "Principal": {
   467          "Service": "opsworks.amazonaws.com"
   468        },
   469        "Action": "sts:AssumeRole"
   470      }
   471    ]
   472  }
   473  EOT
   474  }
   475  
   476  resource "aws_iam_role_policy" "opsworks_service" {
   477      name = "%s_opsworks_service"
   478      role = "${aws_iam_role.opsworks_service.id}"
   479      policy = <<EOT
   480  {
   481    "Statement": [
   482      {
   483        "Action": [
   484          "ec2:*",
   485          "iam:PassRole",
   486          "cloudwatch:GetMetricStatistics",
   487          "elasticloadbalancing:*",
   488          "rds:*"
   489        ],
   490        "Effect": "Allow",
   491        "Resource": ["*"]
   492      }
   493    ]
   494  }
   495  EOT
   496  }
   497  
   498  resource "aws_iam_role" "opsworks_instance" {
   499      name = "%s_opsworks_instance"
   500      assume_role_policy = <<EOT
   501  {
   502    "Version": "2008-10-17",
   503    "Statement": [
   504      {
   505        "Sid": "",
   506        "Effect": "Allow",
   507        "Principal": {
   508          "Service": "ec2.amazonaws.com"
   509        },
   510        "Action": "sts:AssumeRole"
   511      }
   512    ]
   513  }
   514  EOT
   515  }
   516  
   517  resource "aws_iam_instance_profile" "opsworks_instance" {
   518      name = "%s_opsworks_instance"
   519      roles = ["${aws_iam_role.opsworks_instance.name}"]
   520  }
   521  `, name, name, name, name, name)
   522  }
   523  
   524  func testAccAWSOpsworksStackConfigVpcUpdate(name string) string {
   525  	return fmt.Sprintf(`
   526  resource "aws_vpc" "tf-acc" {
   527    cidr_block = "10.3.5.0/24"
   528  }
   529  resource "aws_subnet" "tf-acc" {
   530    vpc_id = "${aws_vpc.tf-acc.id}"
   531    cidr_block = "${aws_vpc.tf-acc.cidr_block}"
   532    availability_zone = "us-west-2a"
   533  }
   534  resource "aws_opsworks_stack" "tf-acc" {
   535    name = "%s"
   536    region = "us-west-2"
   537    vpc_id = "${aws_vpc.tf-acc.id}"
   538    default_subnet_id = "${aws_subnet.tf-acc.id}"
   539    service_role_arn = "${aws_iam_role.opsworks_service.arn}"
   540    default_instance_profile_arn = "${aws_iam_instance_profile.opsworks_instance.arn}"
   541    default_os = "Amazon Linux 2015.09"
   542    default_root_device_type = "ebs"
   543    custom_json = "{\"key\": \"value\"}"
   544    configuration_manager_version = "11.10"
   545    use_opsworks_security_groups = false
   546    use_custom_cookbooks = true
   547    manage_berkshelf = true
   548    custom_cookbooks_source {
   549      type = "git"
   550      revision = "master"
   551      url = "https://github.com/aws/opsworks-example-cookbooks.git"
   552    }
   553  }
   554  
   555  resource "aws_iam_role" "opsworks_service" {
   556      name = "%s_opsworks_service"
   557      assume_role_policy = <<EOT
   558  {
   559    "Version": "2008-10-17",
   560    "Statement": [
   561      {
   562        "Sid": "",
   563        "Effect": "Allow",
   564        "Principal": {
   565          "Service": "opsworks.amazonaws.com"
   566        },
   567        "Action": "sts:AssumeRole"
   568      }
   569    ]
   570  }
   571  EOT
   572  }
   573  
   574  resource "aws_iam_role_policy" "opsworks_service" {
   575      name = "%s_opsworks_service"
   576      role = "${aws_iam_role.opsworks_service.id}"
   577      policy = <<EOT
   578  {
   579    "Statement": [
   580      {
   581        "Action": [
   582          "ec2:*",
   583          "iam:PassRole",
   584          "cloudwatch:GetMetricStatistics",
   585          "elasticloadbalancing:*",
   586          "rds:*"
   587        ],
   588        "Effect": "Allow",
   589        "Resource": ["*"]
   590      }
   591    ]
   592  }
   593  EOT
   594  }
   595  
   596  resource "aws_iam_role" "opsworks_instance" {
   597      name = "%s_opsworks_instance"
   598      assume_role_policy = <<EOT
   599  {
   600    "Version": "2008-10-17",
   601    "Statement": [
   602      {
   603        "Sid": "",
   604        "Effect": "Allow",
   605        "Principal": {
   606          "Service": "ec2.amazonaws.com"
   607        },
   608        "Action": "sts:AssumeRole"
   609      }
   610    ]
   611  }
   612  EOT
   613  }
   614  
   615  resource "aws_iam_instance_profile" "opsworks_instance" {
   616      name = "%s_opsworks_instance"
   617      roles = ["${aws_iam_role.opsworks_instance.name}"]
   618  }
   619  
   620  `, name, name, name, name, name)
   621  }