github.com/joshgarnett/terraform@v0.5.4-0.20160219181435-92dc20bb3594/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 %s, saved %s", desiredInString, enabled) 281 } 282 283 return nil 284 } 285 } 286 287 func testAccCheckCloudTrailKmsKeyIdEquals(n string, desired string, trail *cloudtrail.Trail) resource.TestCheckFunc { 288 return func(s *terraform.State) error { 289 rs, ok := s.RootModule().Resources[n] 290 if !ok { 291 return fmt.Errorf("Not found: %s", n) 292 } 293 294 if desired != "" && trail.KmsKeyId == nil { 295 return fmt.Errorf("No KmsKeyId attribute present in trail: %s, expected %s", 296 trail, desired) 297 } 298 299 // work around string pointer 300 var kmsKeyIdInString string 301 if trail.KmsKeyId == nil { 302 kmsKeyIdInString = "" 303 } else { 304 kmsKeyIdInString = *trail.KmsKeyId 305 } 306 307 if kmsKeyIdInString != desired { 308 return fmt.Errorf("Expected KMS Key ID %q to equal %q", 309 *trail.KmsKeyId, desired) 310 } 311 312 kmsKeyId, ok := rs.Primary.Attributes["kms_key_id"] 313 if desired != "" && !ok { 314 return fmt.Errorf("No kms_key_id attribute defined for %s", n) 315 } 316 if kmsKeyId != desired { 317 return fmt.Errorf("Expected KMS Key ID %q, saved %q", desired, kmsKeyId) 318 } 319 320 return nil 321 } 322 } 323 324 func testAccCheckAWSCloudTrailDestroy(s *terraform.State) error { 325 conn := testAccProvider.Meta().(*AWSClient).cloudtrailconn 326 327 for _, rs := range s.RootModule().Resources { 328 if rs.Type != "aws_cloudtrail" { 329 continue 330 } 331 332 params := cloudtrail.DescribeTrailsInput{ 333 TrailNameList: []*string{aws.String(rs.Primary.ID)}, 334 } 335 336 resp, err := conn.DescribeTrails(¶ms) 337 338 if err == nil { 339 if len(resp.TrailList) != 0 && 340 *resp.TrailList[0].Name == rs.Primary.ID { 341 return fmt.Errorf("CloudTrail still exists: %s", rs.Primary.ID) 342 } 343 } 344 } 345 346 return nil 347 } 348 349 func testAccCheckCloudTrailLoadTags(trail *cloudtrail.Trail, tags *[]*cloudtrail.Tag) resource.TestCheckFunc { 350 return func(s *terraform.State) error { 351 conn := testAccProvider.Meta().(*AWSClient).cloudtrailconn 352 input := cloudtrail.ListTagsInput{ 353 ResourceIdList: []*string{trail.TrailARN}, 354 } 355 out, err := conn.ListTags(&input) 356 if err != nil { 357 return err 358 } 359 log.Printf("[DEBUG] Received CloudTrail tags during test: %s", out) 360 if len(out.ResourceTagList) > 0 { 361 *tags = out.ResourceTagList[0].TagsList 362 } 363 log.Printf("[DEBUG] Loading CloudTrail tags into a var: %s", *tags) 364 return nil 365 } 366 } 367 368 var cloudTrailRandInt = rand.New(rand.NewSource(time.Now().UnixNano())).Int() 369 370 var testAccAWSCloudTrailConfig = fmt.Sprintf(` 371 resource "aws_cloudtrail" "foobar" { 372 name = "tf-trail-foobar" 373 s3_bucket_name = "${aws_s3_bucket.foo.id}" 374 } 375 376 resource "aws_s3_bucket" "foo" { 377 bucket = "tf-test-trail-%d" 378 force_destroy = true 379 policy = <<POLICY 380 { 381 "Version": "2012-10-17", 382 "Statement": [ 383 { 384 "Sid": "AWSCloudTrailAclCheck", 385 "Effect": "Allow", 386 "Principal": "*", 387 "Action": "s3:GetBucketAcl", 388 "Resource": "arn:aws:s3:::tf-test-trail-%d" 389 }, 390 { 391 "Sid": "AWSCloudTrailWrite", 392 "Effect": "Allow", 393 "Principal": "*", 394 "Action": "s3:PutObject", 395 "Resource": "arn:aws:s3:::tf-test-trail-%d/*", 396 "Condition": { 397 "StringEquals": { 398 "s3:x-amz-acl": "bucket-owner-full-control" 399 } 400 } 401 } 402 ] 403 } 404 POLICY 405 } 406 `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 407 408 var testAccAWSCloudTrailConfigModified = fmt.Sprintf(` 409 resource "aws_cloudtrail" "foobar" { 410 name = "tf-trail-foobar" 411 s3_bucket_name = "${aws_s3_bucket.foo.id}" 412 s3_key_prefix = "/prefix" 413 include_global_service_events = false 414 enable_logging = false 415 } 416 417 resource "aws_s3_bucket" "foo" { 418 bucket = "tf-test-trail-%d" 419 force_destroy = true 420 policy = <<POLICY 421 { 422 "Version": "2012-10-17", 423 "Statement": [ 424 { 425 "Sid": "AWSCloudTrailAclCheck", 426 "Effect": "Allow", 427 "Principal": "*", 428 "Action": "s3:GetBucketAcl", 429 "Resource": "arn:aws:s3:::tf-test-trail-%d" 430 }, 431 { 432 "Sid": "AWSCloudTrailWrite", 433 "Effect": "Allow", 434 "Principal": "*", 435 "Action": "s3:PutObject", 436 "Resource": "arn:aws:s3:::tf-test-trail-%d/*", 437 "Condition": { 438 "StringEquals": { 439 "s3:x-amz-acl": "bucket-owner-full-control" 440 } 441 } 442 } 443 ] 444 } 445 POLICY 446 } 447 `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 448 449 var testAccAWSCloudTrailConfigMultiRegion = fmt.Sprintf(` 450 resource "aws_cloudtrail" "foobar" { 451 name = "tf-trail-foobar" 452 s3_bucket_name = "${aws_s3_bucket.foo.id}" 453 is_multi_region_trail = true 454 } 455 456 resource "aws_s3_bucket" "foo" { 457 bucket = "tf-test-trail-%d" 458 force_destroy = true 459 policy = <<POLICY 460 { 461 "Version": "2012-10-17", 462 "Statement": [ 463 { 464 "Sid": "AWSCloudTrailAclCheck", 465 "Effect": "Allow", 466 "Principal": "*", 467 "Action": "s3:GetBucketAcl", 468 "Resource": "arn:aws:s3:::tf-test-trail-%d" 469 }, 470 { 471 "Sid": "AWSCloudTrailWrite", 472 "Effect": "Allow", 473 "Principal": "*", 474 "Action": "s3:PutObject", 475 "Resource": "arn:aws:s3:::tf-test-trail-%d/*", 476 "Condition": { 477 "StringEquals": { 478 "s3:x-amz-acl": "bucket-owner-full-control" 479 } 480 } 481 } 482 ] 483 } 484 POLICY 485 } 486 `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 487 488 var testAccAWSCloudTrailConfig_logValidation = fmt.Sprintf(` 489 resource "aws_cloudtrail" "foobar" { 490 name = "tf-acc-trail-log-validation-test" 491 s3_bucket_name = "${aws_s3_bucket.foo.id}" 492 is_multi_region_trail = true 493 include_global_service_events = true 494 enable_log_file_validation = true 495 } 496 497 resource "aws_s3_bucket" "foo" { 498 bucket = "tf-test-trail-%d" 499 force_destroy = true 500 policy = <<POLICY 501 { 502 "Version": "2012-10-17", 503 "Statement": [ 504 { 505 "Sid": "AWSCloudTrailAclCheck", 506 "Effect": "Allow", 507 "Principal": "*", 508 "Action": "s3:GetBucketAcl", 509 "Resource": "arn:aws:s3:::tf-test-trail-%d" 510 }, 511 { 512 "Sid": "AWSCloudTrailWrite", 513 "Effect": "Allow", 514 "Principal": "*", 515 "Action": "s3:PutObject", 516 "Resource": "arn:aws:s3:::tf-test-trail-%d/*", 517 "Condition": { 518 "StringEquals": { 519 "s3:x-amz-acl": "bucket-owner-full-control" 520 } 521 } 522 } 523 ] 524 } 525 POLICY 526 } 527 `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 528 529 var testAccAWSCloudTrailConfig_logValidationModified = fmt.Sprintf(` 530 resource "aws_cloudtrail" "foobar" { 531 name = "tf-acc-trail-log-validation-test" 532 s3_bucket_name = "${aws_s3_bucket.foo.id}" 533 include_global_service_events = true 534 } 535 536 resource "aws_s3_bucket" "foo" { 537 bucket = "tf-test-trail-%d" 538 force_destroy = true 539 policy = <<POLICY 540 { 541 "Version": "2012-10-17", 542 "Statement": [ 543 { 544 "Sid": "AWSCloudTrailAclCheck", 545 "Effect": "Allow", 546 "Principal": "*", 547 "Action": "s3:GetBucketAcl", 548 "Resource": "arn:aws:s3:::tf-test-trail-%d" 549 }, 550 { 551 "Sid": "AWSCloudTrailWrite", 552 "Effect": "Allow", 553 "Principal": "*", 554 "Action": "s3:PutObject", 555 "Resource": "arn:aws:s3:::tf-test-trail-%d/*", 556 "Condition": { 557 "StringEquals": { 558 "s3:x-amz-acl": "bucket-owner-full-control" 559 } 560 } 561 } 562 ] 563 } 564 POLICY 565 } 566 `, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 567 568 var testAccAWSCloudTrailConfig_tags_tpl = ` 569 resource "aws_cloudtrail" "foobar" { 570 name = "tf-acc-trail-log-validation-test" 571 s3_bucket_name = "${aws_s3_bucket.foo.id}" 572 %s 573 } 574 575 resource "aws_s3_bucket" "foo" { 576 bucket = "tf-test-trail-%d" 577 force_destroy = true 578 policy = <<POLICY 579 { 580 "Version": "2012-10-17", 581 "Statement": [ 582 { 583 "Sid": "AWSCloudTrailAclCheck", 584 "Effect": "Allow", 585 "Principal": "*", 586 "Action": "s3:GetBucketAcl", 587 "Resource": "arn:aws:s3:::tf-test-trail-%d" 588 }, 589 { 590 "Sid": "AWSCloudTrailWrite", 591 "Effect": "Allow", 592 "Principal": "*", 593 "Action": "s3:PutObject", 594 "Resource": "arn:aws:s3:::tf-test-trail-%d/*", 595 "Condition": { 596 "StringEquals": { 597 "s3:x-amz-acl": "bucket-owner-full-control" 598 } 599 } 600 } 601 ] 602 } 603 POLICY 604 } 605 ` 606 607 var testAccAWSCloudTrailConfig_tags = fmt.Sprintf(testAccAWSCloudTrailConfig_tags_tpl, 608 `tags { 609 Foo = "moo" 610 Pooh = "hi" 611 }`, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 612 var testAccAWSCloudTrailConfig_tagsModified = fmt.Sprintf(testAccAWSCloudTrailConfig_tags_tpl, 613 `tags { 614 Foo = "moo" 615 Pooh = "hi" 616 Moo = "boom" 617 }`, cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt) 618 var testAccAWSCloudTrailConfig_tagsModifiedAgain = fmt.Sprintf(testAccAWSCloudTrailConfig_tags_tpl, 619 "", cloudTrailRandInt, cloudTrailRandInt, cloudTrailRandInt)