github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_cloudtrail_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"testing"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/service/cloudtrail"
    10  	"github.com/hashicorp/terraform/helper/acctest"
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/terraform"
    13  	"regexp"
    14  )
    15  
    16  func TestAccAWSCloudTrail_basic(t *testing.T) {
    17  	var trail cloudtrail.Trail
    18  	cloudTrailRandInt := acctest.RandInt()
    19  
    20  	resource.Test(t, resource.TestCase{
    21  		PreCheck:     func() { testAccPreCheck(t) },
    22  		Providers:    testAccProviders,
    23  		CheckDestroy: testAccCheckAWSCloudTrailDestroy,
    24  		Steps: []resource.TestStep{
    25  			{
    26  				Config: testAccAWSCloudTrailConfig(cloudTrailRandInt),
    27  				Check: resource.ComposeTestCheckFunc(
    28  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
    29  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "include_global_service_events", "true"),
    30  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
    31  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
    32  				),
    33  			},
    34  			{
    35  				Config: testAccAWSCloudTrailConfigModified(cloudTrailRandInt),
    36  				Check: resource.ComposeTestCheckFunc(
    37  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
    38  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "s3_key_prefix", "/prefix"),
    39  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "include_global_service_events", "false"),
    40  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
    41  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
    42  				),
    43  			},
    44  		},
    45  	})
    46  }
    47  
    48  func TestAccAWSCloudTrail_enable_logging(t *testing.T) {
    49  	var trail cloudtrail.Trail
    50  	cloudTrailRandInt := acctest.RandInt()
    51  
    52  	resource.Test(t, resource.TestCase{
    53  		PreCheck:     func() { testAccPreCheck(t) },
    54  		Providers:    testAccProviders,
    55  		CheckDestroy: testAccCheckAWSCloudTrailDestroy,
    56  		Steps: []resource.TestStep{
    57  			{
    58  				Config: testAccAWSCloudTrailConfig(cloudTrailRandInt),
    59  				Check: resource.ComposeTestCheckFunc(
    60  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
    61  					// AWS will create the trail with logging turned off.
    62  					// Test that "enable_logging" default works.
    63  					testAccCheckCloudTrailLoggingEnabled("aws_cloudtrail.foobar", true, &trail),
    64  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
    65  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
    66  				),
    67  			},
    68  			{
    69  				Config: testAccAWSCloudTrailConfigModified(cloudTrailRandInt),
    70  				Check: resource.ComposeTestCheckFunc(
    71  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
    72  					testAccCheckCloudTrailLoggingEnabled("aws_cloudtrail.foobar", false, &trail),
    73  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
    74  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
    75  				),
    76  			},
    77  			{
    78  				Config: testAccAWSCloudTrailConfig(cloudTrailRandInt),
    79  				Check: resource.ComposeTestCheckFunc(
    80  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
    81  					testAccCheckCloudTrailLoggingEnabled("aws_cloudtrail.foobar", true, &trail),
    82  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
    83  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
    84  				),
    85  			},
    86  		},
    87  	})
    88  }
    89  
    90  func TestAccAWSCloudTrail_is_multi_region(t *testing.T) {
    91  	var trail cloudtrail.Trail
    92  	cloudTrailRandInt := acctest.RandInt()
    93  
    94  	resource.Test(t, resource.TestCase{
    95  		PreCheck:     func() { testAccPreCheck(t) },
    96  		Providers:    testAccProviders,
    97  		CheckDestroy: testAccCheckAWSCloudTrailDestroy,
    98  		Steps: []resource.TestStep{
    99  			{
   100  				Config: testAccAWSCloudTrailConfig(cloudTrailRandInt),
   101  				Check: resource.ComposeTestCheckFunc(
   102  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   103  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "is_multi_region_trail", "false"),
   104  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   105  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   106  				),
   107  			},
   108  			{
   109  				Config: testAccAWSCloudTrailConfigMultiRegion(cloudTrailRandInt),
   110  				Check: resource.ComposeTestCheckFunc(
   111  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   112  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "is_multi_region_trail", "true"),
   113  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   114  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   115  				),
   116  			},
   117  			{
   118  				Config: testAccAWSCloudTrailConfig(cloudTrailRandInt),
   119  				Check: resource.ComposeTestCheckFunc(
   120  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   121  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "is_multi_region_trail", "false"),
   122  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   123  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   124  				),
   125  			},
   126  		},
   127  	})
   128  }
   129  
   130  func TestAccAWSCloudTrail_logValidation(t *testing.T) {
   131  	var trail cloudtrail.Trail
   132  	cloudTrailRandInt := acctest.RandInt()
   133  
   134  	resource.Test(t, resource.TestCase{
   135  		PreCheck:     func() { testAccPreCheck(t) },
   136  		Providers:    testAccProviders,
   137  		CheckDestroy: testAccCheckAWSCloudTrailDestroy,
   138  		Steps: []resource.TestStep{
   139  			{
   140  				Config: testAccAWSCloudTrailConfig_logValidation(cloudTrailRandInt),
   141  				Check: resource.ComposeTestCheckFunc(
   142  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   143  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "s3_key_prefix", ""),
   144  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "include_global_service_events", "true"),
   145  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", true, &trail),
   146  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   147  				),
   148  			},
   149  			{
   150  				Config: testAccAWSCloudTrailConfig_logValidationModified(cloudTrailRandInt),
   151  				Check: resource.ComposeTestCheckFunc(
   152  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   153  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "s3_key_prefix", ""),
   154  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "include_global_service_events", "true"),
   155  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   156  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   157  				),
   158  			},
   159  		},
   160  	})
   161  }
   162  
   163  func TestAccAWSCloudTrail_kmsKey(t *testing.T) {
   164  	var trail cloudtrail.Trail
   165  	cloudTrailRandInt := acctest.RandInt()
   166  	keyRegex := regexp.MustCompile("^arn:aws:([a-zA-Z0-9\\-])+:([a-z]{2}-[a-z]+-\\d{1})?:(\\d{12})?:(.*)$")
   167  
   168  	resource.Test(t, resource.TestCase{
   169  		PreCheck:     func() { testAccPreCheck(t) },
   170  		Providers:    testAccProviders,
   171  		CheckDestroy: testAccCheckAWSCloudTrailDestroy,
   172  		Steps: []resource.TestStep{
   173  			{
   174  				Config: testAccAWSCloudTrailConfig_kmsKey(cloudTrailRandInt),
   175  				Check: resource.ComposeTestCheckFunc(
   176  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   177  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "s3_key_prefix", ""),
   178  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "include_global_service_events", "true"),
   179  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   180  					resource.TestMatchResourceAttr("aws_cloudtrail.foobar", "kms_key_id", keyRegex),
   181  				),
   182  			},
   183  		},
   184  	})
   185  }
   186  
   187  func TestAccAWSCloudTrail_tags(t *testing.T) {
   188  	var trail cloudtrail.Trail
   189  	var trailTags []*cloudtrail.Tag
   190  	var trailTagsModified []*cloudtrail.Tag
   191  	cloudTrailRandInt := acctest.RandInt()
   192  
   193  	resource.Test(t, resource.TestCase{
   194  		PreCheck:     func() { testAccPreCheck(t) },
   195  		Providers:    testAccProviders,
   196  		CheckDestroy: testAccCheckAWSCloudTrailDestroy,
   197  		Steps: []resource.TestStep{
   198  			{
   199  				Config: testAccAWSCloudTrailConfig_tags(cloudTrailRandInt),
   200  				Check: resource.ComposeTestCheckFunc(
   201  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   202  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "tags.%", "2"),
   203  					testAccCheckCloudTrailLoadTags(&trail, &trailTags),
   204  					testAccCheckCloudTrailCheckTags(&trailTags, map[string]string{"Foo": "moo", "Pooh": "hi"}),
   205  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   206  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   207  				),
   208  			},
   209  			{
   210  				Config: testAccAWSCloudTrailConfig_tagsModified(cloudTrailRandInt),
   211  				Check: resource.ComposeTestCheckFunc(
   212  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   213  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "tags.%", "3"),
   214  					testAccCheckCloudTrailLoadTags(&trail, &trailTagsModified),
   215  					testAccCheckCloudTrailCheckTags(&trailTagsModified, map[string]string{"Foo": "moo", "Moo": "boom", "Pooh": "hi"}),
   216  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   217  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   218  				),
   219  			},
   220  			{
   221  				Config: testAccAWSCloudTrailConfig_tagsModifiedAgain(cloudTrailRandInt),
   222  				Check: resource.ComposeTestCheckFunc(
   223  					testAccCheckCloudTrailExists("aws_cloudtrail.foobar", &trail),
   224  					resource.TestCheckResourceAttr("aws_cloudtrail.foobar", "tags.%", "0"),
   225  					testAccCheckCloudTrailLoadTags(&trail, &trailTagsModified),
   226  					testAccCheckCloudTrailCheckTags(&trailTagsModified, map[string]string{}),
   227  					testAccCheckCloudTrailLogValidationEnabled("aws_cloudtrail.foobar", false, &trail),
   228  					testAccCheckCloudTrailKmsKeyIdEquals("aws_cloudtrail.foobar", "", &trail),
   229  				),
   230  			},
   231  		},
   232  	})
   233  }
   234  
   235  func testAccCheckCloudTrailExists(n string, trail *cloudtrail.Trail) resource.TestCheckFunc {
   236  	return func(s *terraform.State) error {
   237  		rs, ok := s.RootModule().Resources[n]
   238  		if !ok {
   239  			return fmt.Errorf("Not found: %s", n)
   240  		}
   241  
   242  		conn := testAccProvider.Meta().(*AWSClient).cloudtrailconn
   243  		params := cloudtrail.DescribeTrailsInput{
   244  			TrailNameList: []*string{aws.String(rs.Primary.ID)},
   245  		}
   246  		resp, err := conn.DescribeTrails(&params)
   247  		if err != nil {
   248  			return err
   249  		}
   250  		if len(resp.TrailList) == 0 {
   251  			return fmt.Errorf("Trail not found")
   252  		}
   253  		*trail = *resp.TrailList[0]
   254  
   255  		return nil
   256  	}
   257  }
   258  
   259  func testAccCheckCloudTrailLoggingEnabled(n string, desired bool, trail *cloudtrail.Trail) resource.TestCheckFunc {
   260  	return func(s *terraform.State) error {
   261  		rs, ok := s.RootModule().Resources[n]
   262  		if !ok {
   263  			return fmt.Errorf("Not found: %s", n)
   264  		}
   265  
   266  		conn := testAccProvider.Meta().(*AWSClient).cloudtrailconn
   267  		params := cloudtrail.GetTrailStatusInput{
   268  			Name: aws.String(rs.Primary.ID),
   269  		}
   270  		resp, err := conn.GetTrailStatus(&params)
   271  
   272  		if err != nil {
   273  			return err
   274  		}
   275  		if *resp.IsLogging != desired {
   276  			return fmt.Errorf("Expected logging status %t, given %t", desired, *resp.IsLogging)
   277  		}
   278  
   279  		return nil
   280  	}
   281  }
   282  
   283  func testAccCheckCloudTrailLogValidationEnabled(n string, desired bool, trail *cloudtrail.Trail) resource.TestCheckFunc {
   284  	return func(s *terraform.State) error {
   285  		rs, ok := s.RootModule().Resources[n]
   286  		if !ok {
   287  			return fmt.Errorf("Not found: %s", n)
   288  		}
   289  
   290  		if trail.LogFileValidationEnabled == nil {
   291  			return fmt.Errorf("No LogFileValidationEnabled attribute present in trail: %s", trail)
   292  		}
   293  
   294  		if *trail.LogFileValidationEnabled != desired {
   295  			return fmt.Errorf("Expected log validation status %t, given %t", desired,
   296  				*trail.LogFileValidationEnabled)
   297  		}
   298  
   299  		// local state comparison
   300  		enabled, ok := rs.Primary.Attributes["enable_log_file_validation"]
   301  		if !ok {
   302  			return fmt.Errorf("No enable_log_file_validation attribute defined for %s, expected %t",
   303  				n, desired)
   304  		}
   305  		desiredInString := fmt.Sprintf("%t", desired)
   306  		if enabled != desiredInString {
   307  			return fmt.Errorf("Expected log validation status %s, saved %s", desiredInString, enabled)
   308  		}
   309  
   310  		return nil
   311  	}
   312  }
   313  
   314  func testAccCheckCloudTrailKmsKeyIdEquals(n string, desired string, trail *cloudtrail.Trail) resource.TestCheckFunc {
   315  	return func(s *terraform.State) error {
   316  		rs, ok := s.RootModule().Resources[n]
   317  		if !ok {
   318  			return fmt.Errorf("Not found: %s", n)
   319  		}
   320  
   321  		if desired != "" && trail.KmsKeyId == nil {
   322  			return fmt.Errorf("No KmsKeyId attribute present in trail: %s, expected %s",
   323  				trail, desired)
   324  		}
   325  
   326  		// work around string pointer
   327  		var kmsKeyIdInString string
   328  		if trail.KmsKeyId == nil {
   329  			kmsKeyIdInString = ""
   330  		} else {
   331  			kmsKeyIdInString = *trail.KmsKeyId
   332  		}
   333  
   334  		if kmsKeyIdInString != desired {
   335  			return fmt.Errorf("Expected KMS Key ID %q to equal %q",
   336  				*trail.KmsKeyId, desired)
   337  		}
   338  
   339  		kmsKeyId, ok := rs.Primary.Attributes["kms_key_id"]
   340  		if desired != "" && !ok {
   341  			return fmt.Errorf("No kms_key_id attribute defined for %s", n)
   342  		}
   343  		if kmsKeyId != desired {
   344  			return fmt.Errorf("Expected KMS Key ID %q, saved %q", desired, kmsKeyId)
   345  		}
   346  
   347  		return nil
   348  	}
   349  }
   350  
   351  func testAccCheckAWSCloudTrailDestroy(s *terraform.State) error {
   352  	conn := testAccProvider.Meta().(*AWSClient).cloudtrailconn
   353  
   354  	for _, rs := range s.RootModule().Resources {
   355  		if rs.Type != "aws_cloudtrail" {
   356  			continue
   357  		}
   358  
   359  		params := cloudtrail.DescribeTrailsInput{
   360  			TrailNameList: []*string{aws.String(rs.Primary.ID)},
   361  		}
   362  
   363  		resp, err := conn.DescribeTrails(&params)
   364  
   365  		if err == nil {
   366  			if len(resp.TrailList) != 0 &&
   367  				*resp.TrailList[0].Name == rs.Primary.ID {
   368  				return fmt.Errorf("CloudTrail still exists: %s", rs.Primary.ID)
   369  			}
   370  		}
   371  	}
   372  
   373  	return nil
   374  }
   375  
   376  func testAccCheckCloudTrailLoadTags(trail *cloudtrail.Trail, tags *[]*cloudtrail.Tag) resource.TestCheckFunc {
   377  	return func(s *terraform.State) error {
   378  		conn := testAccProvider.Meta().(*AWSClient).cloudtrailconn
   379  		input := cloudtrail.ListTagsInput{
   380  			ResourceIdList: []*string{trail.TrailARN},
   381  		}
   382  		out, err := conn.ListTags(&input)
   383  		if err != nil {
   384  			return err
   385  		}
   386  		log.Printf("[DEBUG] Received CloudTrail tags during test: %s", out)
   387  		if len(out.ResourceTagList) > 0 {
   388  			*tags = out.ResourceTagList[0].TagsList
   389  		}
   390  		log.Printf("[DEBUG] Loading CloudTrail tags into a var: %s", *tags)
   391  		return nil
   392  	}
   393  }
   394  
   395  func testAccAWSCloudTrailConfig(cloudTrailRandInt int) string {
   396  	return fmt.Sprintf(`
   397  resource "aws_cloudtrail" "foobar" {
   398      name = "tf-trail-foobar-%d"
   399      s3_bucket_name = "${aws_s3_bucket.foo.id}"
   400  }
   401  
   402  resource "aws_s3_bucket" "foo" {
   403  	bucket = "tf-test-trail-%d"
   404  	force_destroy = true
   405  	policy = <<POLICY
   406  {
   407  	"Version": "2012-10-17",
   408  	"Statement": [
   409  		{
   410  			"Sid": "AWSCloudTrailAclCheck",
   411  			"Effect": "Allow",
   412  			"Principal": "*",
   413  			"Action": "s3:GetBucketAcl",
   414  			"Resource": "arn:aws:s3:::tf-test-trail-%d"
   415  		},
   416  		{
   417  			"Sid": "AWSCloudTrailWrite",
   418  			"Effect": "Allow",
   419  			"Principal": "*",
   420  			"Action": "s3:PutObject",
   421  			"Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   422  			"Condition": {
   423  				"StringEquals": {
   424  					"s3:x-amz-acl": "bucket-owner-full-control"
   425  				}
   426  			}
   427  		}
   428  	]
   429  }
   430  POLICY
   431  }
   432  `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   433  }
   434  
   435  func testAccAWSCloudTrailConfigModified(cloudTrailRandInt int) string {
   436  	return fmt.Sprintf(`
   437  resource "aws_cloudtrail" "foobar" {
   438      name = "tf-trail-foobar-%d"
   439      s3_bucket_name = "${aws_s3_bucket.foo.id}"
   440      s3_key_prefix = "/prefix"
   441      include_global_service_events = false
   442      enable_logging = false
   443  }
   444  
   445  resource "aws_s3_bucket" "foo" {
   446  	bucket = "tf-test-trail-%d"
   447  	force_destroy = true
   448  	policy = <<POLICY
   449  {
   450  	"Version": "2012-10-17",
   451  	"Statement": [
   452  		{
   453  			"Sid": "AWSCloudTrailAclCheck",
   454  			"Effect": "Allow",
   455  			"Principal": "*",
   456  			"Action": "s3:GetBucketAcl",
   457  			"Resource": "arn:aws:s3:::tf-test-trail-%d"
   458  		},
   459  		{
   460  			"Sid": "AWSCloudTrailWrite",
   461  			"Effect": "Allow",
   462  			"Principal": "*",
   463  			"Action": "s3:PutObject",
   464  			"Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   465  			"Condition": {
   466  				"StringEquals": {
   467  					"s3:x-amz-acl": "bucket-owner-full-control"
   468  				}
   469  			}
   470  		}
   471  	]
   472  }
   473  POLICY
   474  }
   475  `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   476  }
   477  
   478  func testAccAWSCloudTrailConfigMultiRegion(cloudTrailRandInt int) string {
   479  	return fmt.Sprintf(`
   480  resource "aws_cloudtrail" "foobar" {
   481      name = "tf-trail-foobar-%d"
   482      s3_bucket_name = "${aws_s3_bucket.foo.id}"
   483      is_multi_region_trail = true
   484  }
   485  
   486  resource "aws_s3_bucket" "foo" {
   487  	bucket = "tf-test-trail-%d"
   488  	force_destroy = true
   489  	policy = <<POLICY
   490  {
   491  	"Version": "2012-10-17",
   492  	"Statement": [
   493  		{
   494  			"Sid": "AWSCloudTrailAclCheck",
   495  			"Effect": "Allow",
   496  			"Principal": "*",
   497  			"Action": "s3:GetBucketAcl",
   498  			"Resource": "arn:aws:s3:::tf-test-trail-%d"
   499  		},
   500  		{
   501  			"Sid": "AWSCloudTrailWrite",
   502  			"Effect": "Allow",
   503  			"Principal": "*",
   504  			"Action": "s3:PutObject",
   505  			"Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   506  			"Condition": {
   507  				"StringEquals": {
   508  					"s3:x-amz-acl": "bucket-owner-full-control"
   509  				}
   510  			}
   511  		}
   512  	]
   513  }
   514  POLICY
   515  }
   516  `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   517  }
   518  
   519  func testAccAWSCloudTrailConfig_logValidation(cloudTrailRandInt int) string {
   520  	return fmt.Sprintf(`
   521  resource "aws_cloudtrail" "foobar" {
   522      name = "tf-acc-trail-log-validation-test-%d"
   523      s3_bucket_name = "${aws_s3_bucket.foo.id}"
   524      is_multi_region_trail = true
   525      include_global_service_events = true
   526      enable_log_file_validation = true
   527  }
   528  
   529  resource "aws_s3_bucket" "foo" {
   530  	bucket = "tf-test-trail-%d"
   531  	force_destroy = true
   532  	policy = <<POLICY
   533  {
   534  	"Version": "2012-10-17",
   535  	"Statement": [
   536  		{
   537  			"Sid": "AWSCloudTrailAclCheck",
   538  			"Effect": "Allow",
   539  			"Principal": "*",
   540  			"Action": "s3:GetBucketAcl",
   541  			"Resource": "arn:aws:s3:::tf-test-trail-%d"
   542  		},
   543  		{
   544  			"Sid": "AWSCloudTrailWrite",
   545  			"Effect": "Allow",
   546  			"Principal": "*",
   547  			"Action": "s3:PutObject",
   548  			"Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   549  			"Condition": {
   550  				"StringEquals": {
   551  					"s3:x-amz-acl": "bucket-owner-full-control"
   552  				}
   553  			}
   554  		}
   555  	]
   556  }
   557  POLICY
   558  }
   559  `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   560  }
   561  
   562  func testAccAWSCloudTrailConfig_logValidationModified(cloudTrailRandInt int) string {
   563  	return fmt.Sprintf(`
   564  resource "aws_cloudtrail" "foobar" {
   565      name = "tf-acc-trail-log-validation-test-%d"
   566      s3_bucket_name = "${aws_s3_bucket.foo.id}"
   567      include_global_service_events = true
   568  }
   569  
   570  resource "aws_s3_bucket" "foo" {
   571  	bucket = "tf-test-trail-%d"
   572  	force_destroy = true
   573  	policy = <<POLICY
   574  {
   575  	"Version": "2012-10-17",
   576  	"Statement": [
   577  		{
   578  			"Sid": "AWSCloudTrailAclCheck",
   579  			"Effect": "Allow",
   580  			"Principal": "*",
   581  			"Action": "s3:GetBucketAcl",
   582  			"Resource": "arn:aws:s3:::tf-test-trail-%d"
   583  		},
   584  		{
   585  			"Sid": "AWSCloudTrailWrite",
   586  			"Effect": "Allow",
   587  			"Principal": "*",
   588  			"Action": "s3:PutObject",
   589  			"Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   590  			"Condition": {
   591  				"StringEquals": {
   592  					"s3:x-amz-acl": "bucket-owner-full-control"
   593  				}
   594  			}
   595  		}
   596  	]
   597  }
   598  POLICY
   599  }
   600  `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   601  }
   602  
   603  func testAccAWSCloudTrailConfig_kmsKey(cloudTrailRandInt int) string {
   604  	return fmt.Sprintf(`
   605  resource "aws_kms_key" "foo" {
   606    description = "Terraform acc test %d"
   607    policy = <<POLICY
   608  {
   609    "Version": "2012-10-17",
   610    "Id": "kms-tf-1",
   611    "Statement": [
   612      {
   613        "Sid": "Enable IAM User Permissions",
   614        "Effect": "Allow",
   615        "Principal": {
   616          "AWS": "*"
   617        },
   618        "Action": "kms:*",
   619        "Resource": "*"
   620      }
   621    ]
   622  }
   623  POLICY
   624  }
   625  
   626  resource "aws_cloudtrail" "foobar" {
   627    name = "tf-acc-trail-log-validation-test-%d"
   628    s3_bucket_name = "${aws_s3_bucket.foo.id}"
   629    include_global_service_events = true
   630    kms_key_id = "${aws_kms_key.foo.arn}"
   631  }
   632  
   633  resource "aws_s3_bucket" "foo" {
   634    bucket = "tf-test-trail-%d"
   635    force_destroy = true
   636    policy = <<POLICY
   637  {
   638    "Version": "2012-10-17",
   639    "Statement": [
   640     {
   641       "Sid": "AWSCloudTrailAclCheck",
   642       "Effect": "Allow",
   643       "Principal": "*",
   644       "Action": "s3:GetBucketAcl",
   645       "Resource": "arn:aws:s3:::tf-test-trail-%d"
   646     },
   647     {
   648       "Sid": "AWSCloudTrailWrite",
   649       "Effect": "Allow",
   650       "Principal": "*",
   651       "Action": "s3:PutObject",
   652       "Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   653       "Condition": {
   654         "StringEquals": {
   655           "s3:x-amz-acl": "bucket-owner-full-control"
   656         }
   657       }
   658     }
   659    ]
   660  }
   661  POLICY
   662  }
   663  `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   664  }
   665  
   666  var testAccAWSCloudTrailConfig_tags_tpl = `
   667  resource "aws_cloudtrail" "foobar" {
   668      name = "tf-acc-trail-log-validation-test-%d"
   669      s3_bucket_name = "${aws_s3_bucket.foo.id}"
   670      %s
   671  }
   672  
   673  resource "aws_s3_bucket" "foo" {
   674  	bucket = "tf-test-trail-%d"
   675  	force_destroy = true
   676  	policy = <<POLICY
   677  {
   678  	"Version": "2012-10-17",
   679  	"Statement": [
   680  		{
   681  			"Sid": "AWSCloudTrailAclCheck",
   682  			"Effect": "Allow",
   683  			"Principal": "*",
   684  			"Action": "s3:GetBucketAcl",
   685  			"Resource": "arn:aws:s3:::tf-test-trail-%d"
   686  		},
   687  		{
   688  			"Sid": "AWSCloudTrailWrite",
   689  			"Effect": "Allow",
   690  			"Principal": "*",
   691  			"Action": "s3:PutObject",
   692  			"Resource": "arn:aws:s3:::tf-test-trail-%d/*",
   693  			"Condition": {
   694  				"StringEquals": {
   695  					"s3:x-amz-acl": "bucket-owner-full-control"
   696  				}
   697  			}
   698  		}
   699  	]
   700  }
   701  POLICY
   702  }
   703  `
   704  
   705  func testAccAWSCloudTrailConfig_tags(cloudTrailRandInt int) string {
   706  	tagsString := `tags {
   707  		Foo = "moo"
   708  		Pooh = "hi"
   709  	}`
   710  	return fmt.Sprintf(testAccAWSCloudTrailConfig_tags_tpl,
   711  		cloudTrailRandInt,
   712  		tagsString,
   713  		cloudTrailRandInt,
   714  		cloudTrailRandInt,
   715  		cloudTrailRandInt)
   716  }
   717  
   718  func testAccAWSCloudTrailConfig_tagsModified(cloudTrailRandInt int) string {
   719  	tagsString := `tags {
   720  		Foo = "moo"
   721  		Pooh = "hi"
   722  		Moo = "boom"
   723  	}`
   724  	return fmt.Sprintf(testAccAWSCloudTrailConfig_tags_tpl,
   725  		cloudTrailRandInt,
   726  		tagsString,
   727  		cloudTrailRandInt,
   728  		cloudTrailRandInt,
   729  		cloudTrailRandInt)
   730  }
   731  
   732  func testAccAWSCloudTrailConfig_tagsModifiedAgain(cloudTrailRandInt int) string {
   733  	return fmt.Sprintf(testAccAWSCloudTrailConfig_tags_tpl,
   734  		cloudTrailRandInt, "", cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)
   735  }