github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_cloudtrail_test.go (about)

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