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