From ddca357f7d2206c91e196a09265563eac6da8117 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 17 Jun 2020 00:37:36 -0400 Subject: [PATCH] docs/provider: Add New Tag Resource section to Contributing Guide Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/9061 --- docs/contributing/contribution-checklists.md | 174 +++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/docs/contributing/contribution-checklists.md b/docs/contributing/contribution-checklists.md index 725fb827b1d..56af5993904 100644 --- a/docs/contributing/contribution-checklists.md +++ b/docs/contributing/contribution-checklists.md @@ -656,6 +656,180 @@ guidelines. This is to avoid conflicts as version updates tend to be fast- moving targets. We will plan to merge the PR with this change first. +### New Tag Resource + +Adding a tag resource, similar to the `aws_ecs_tag` resource, has its own implementation procedure since the resource code and initial acceptance testing functions are automatically generated. The rest of the resource acceptance testing and resource documentation must still be manually created. + +- In `aws/internal/keyvaluetags`: Ensure the service is supported by all generators. Run `make gen` after any modifications. +- In `aws/tag_resources.go`: Add the new `//go:generate` call with the correct service name. Run `make gen` after any modifications. +- In `aws/provider.go`: Add the new resource. +- Run `make test` and ensure there are no failures. +- Create `aws/resource_aws_{service}_tag_test.go` with initial acceptance testing similar to the following (where the parent resource is simple to provision): + +```go + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccAWS{Service}Tag_basic(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_{service}_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheck{Service}TagDestroy, + Steps: []resource.TestStep{ + { + Config: testAcc{Service}TagConfig(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheck{Service}TagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "key1"), + resource.TestCheckResourceAttr(resourceName, "value", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWS{Service}Tag_disappears(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_{service}_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheck{Service}TagDestroy, + Steps: []resource.TestStep{ + { + Config: testAcc{Service}TagConfig(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheck{Service}TagExists(resourceName), + testAccCheckResourceDisappears(testAccProvider, resourceAws{Service}Tag(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAWS{Service}Tag_Value(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_{service}_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheck{Service}TagDestroy, + Steps: []resource.TestStep{ + { + Config: testAcc{Service}TagConfig(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheck{Service}TagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "key1"), + resource.TestCheckResourceAttr(resourceName, "value", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAcc{Service}TagConfig(rName, "key1", "value1updated"), + Check: resource.ComposeTestCheckFunc( + testAccCheck{Service}TagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "key1"), + resource.TestCheckResourceAttr(resourceName, "value", "value1updated"), + ), + }, + }, + }) +} + +func testAcc{Service}TagConfig(rName string, key string, value string) string { + return fmt.Sprintf(` +resource "aws_{service}_{thing}" "test" { + name = %[1]q + + lifecycle { + ignore_changes = [tags] + } +} + +resource "aws_{service}_tag" "test" { + resource_arn = aws_{service}_{thing}.test.arn + key = %[2]q + value = %[3]q +} +`, rName, key, value) +} +``` + +- Run `make testacc TEST=./aws TESTARGS='-run=TestAccAWS{Service}Tags_'` and ensure there are no failures. +- In `website/aws.erb`: Add the new resource. +- Create `website/docs/r/{service}_tag.html.markdown` with initial documentation similar to the following: + +``````markdown +--- +subcategory: "{SERVICE}" +layout: "aws" +page_title: "AWS: aws_{service}_tag" +description: |- + Manages an individual {SERVICE} resource tag +--- + +# Resource: aws_{service}_tag + +Manages an individual {SERVICE} resource tag. This resource should only be used in cases where {SERVICE} resources are created outside Terraform (e.g. {SERVICE} {THING}s implicitly created by {OTHER SERVICE THING}). + +~> **NOTE:** This tagging resource should not be combined with the Terraform resource for managing the parent resource. For example, using `aws_{service}_{thing}` and `aws_{service}_tag` to manage tags of the same {SERVICE} {THING} will cause a perpetual difference where the `aws_{service}_{thing}` resource will try to remove the tag being added by the `aws_{service}_tag` resource. + +~> **NOTE:** This tagging resource does not use the [provider `ignore_tags` configuration](/docs/providers/aws/index.html#ignore_tags). + +## Example Usage + +```hcl +resource "aws_{service}_tag" "example" { + resource_arn = "..." + key = "Name" + value = "Hello World" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `resource_arn` - (Required) Amazon Resource Name (ARN) of the {SERVICE} resource to tag. +* `key` - (Required) Tag name. +* `value` - (Required) Tag value. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - {SERVICE} resource identifier and key, separated by a comma (`,`) + +## Import + +`aws_{service}_tag` can be imported by using the {SERVICE} resource identifier and key, separated by a comma (`,`), e.g. + +``` +$ terraform import aws_{service}_tag.example arn:aws:{service}:us-east-1:123456789012:{thing}/example,Name +``` +`````` + ## New Service Implementing a new AWS service gives Terraform the ability to manage resources in