Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tag Support for aws_waf_rate_based_rule resource #10479

Merged
merged 9 commits into from
Nov 2, 2019
45 changes: 45 additions & 0 deletions aws/resource_aws_waf_rate_based_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/waf"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsWafRateBasedRule() *schema.Resource {
Expand Down Expand Up @@ -64,12 +66,18 @@ func resourceAwsWafRateBasedRule() *schema.Resource {
Required: true,
ValidateFunc: validation.IntAtLeast(100),
},
"tags": tagsSchema(),
"arn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsWafRateBasedRuleCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).wafconn
tags := keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().WafTags()

wr := newWafRetryer(conn)
out, err := wr.RetryWithToken(func(token *string) (interface{}, error) {
Expand All @@ -81,6 +89,10 @@ func resourceAwsWafRateBasedRuleCreate(d *schema.ResourceData, meta interface{})
RateLimit: aws.Int64(int64(d.Get("rate_limit").(int))),
}

if len(tags) > 0 {
params.Tags = tags
}

return conn.CreateRateBasedRule(params)
})
if err != nil {
Expand Down Expand Up @@ -120,6 +132,24 @@ func resourceAwsWafRateBasedRuleRead(d *schema.ResourceData, meta interface{}) e
predicates = append(predicates, predicate)
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: "waf",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("ratebasedrule/%s", d.Id()),
}.String()
d.Set("arn", arn)

tagList, err := conn.ListTagsForResource(&waf.ListTagsForResourceInput{
ResourceARN: aws.String(arn),
})
if err != nil {
return fmt.Errorf("Failed to get WAF Rated Based Rule parameter tags for %s: %s", d.Get("name"), err)
}
if err := d.Set("tags", keyvaluetags.WafKeyValueTags(tagList.TagInfoForResource.TagList).IgnoreAws().Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
}

d.Set("predicates", predicates)
d.Set("name", resp.Rule.Name)
d.Set("metric_name", resp.Rule.MetricName)
Expand All @@ -143,6 +173,21 @@ func resourceAwsWafRateBasedRuleUpdate(d *schema.ResourceData, meta interface{})
}
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: "waf",
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("ratebasedrule/%s", d.Id()),
}.String()

if d.HasChange("tags") {
o, n := d.GetChange("tags")

if err := keyvaluetags.WafUpdateTags(conn, arn, o, n); err != nil {
DrFaust92 marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("error updating tags: %s", err)
}
}

return resourceAwsWafRateBasedRuleRead(d, meta)
}

Expand Down
81 changes: 81 additions & 0 deletions aws/resource_aws_waf_rate_based_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package aws

import (
"fmt"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
Expand All @@ -28,6 +29,7 @@ func TestAccAWSWafRateBasedRule_basic(t *testing.T) {
Config: testAccAWSWafRateBasedRuleConfig(wafRuleName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSWafRateBasedRuleExists(resourceName, &v),
testAccMatchResourceAttrGlobalARN(resourceName, "arn", "waf", regexp.MustCompile(`ratebasedrule/.+`)),
DrFaust92 marked this conversation as resolved.
Show resolved Hide resolved
resource.TestCheckResourceAttr(resourceName, "name", wafRuleName),
resource.TestCheckResourceAttr(resourceName, "predicates.#", "1"),
resource.TestCheckResourceAttr(resourceName, "metric_name", wafRuleName),
Expand Down Expand Up @@ -214,6 +216,54 @@ func TestAccAWSWafRateBasedRule_noPredicates(t *testing.T) {
})
}

func TestAccAWSWafRateBasedRule_Tags(t *testing.T) {
var rule waf.RateBasedRule
ruleName := fmt.Sprintf("wafrule%s", acctest.RandString(5))
resourceName := "aws_waf_rate_based_rule.wafrule"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSWaf(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSWafRateBasedRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSWafRateBasedRuleConfigTags1(ruleName, "key1", "value1"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSWafRateBasedRuleExists(resourceName, &rule),
testAccMatchResourceAttrGlobalARN(resourceName, "arn", "waf", regexp.MustCompile(`ratebasedrule/.+`)),
resource.TestCheckResourceAttr(resourceName, "name", ruleName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"),
),
},
{
Config: testAccAWSWafRateBasedRuleConfigTags2(ruleName, "key1", "value1updated", "key2", "value2"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSWafRateBasedRuleExists(resourceName, &rule),
resource.TestCheckResourceAttr(resourceName, "name", ruleName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
{
Config: testAccAWSWafRateBasedRuleConfigTags1(ruleName, "key2", "value2"),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAWSWafRateBasedRuleExists(resourceName, &rule),
resource.TestCheckResourceAttr(resourceName, "name", ruleName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckAWSWafRateBasedRuleDisappears(v *waf.RateBasedRule) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).wafconn
Expand Down Expand Up @@ -423,3 +473,34 @@ resource "aws_waf_rate_based_rule" "wafrule" {
}
`, name, name)
}

func testAccAWSWafRateBasedRuleConfigTags1(name, tag1Key, tag1Value string) string {
return fmt.Sprintf(`
resource "aws_waf_rate_based_rule" "wafrule" {
name = "%s"
metric_name = "%s"
rate_key = "IP"
rate_limit = 2000

tags = {
%q = %q
}
}
`, name, name, tag1Key, tag1Value)
}

func testAccAWSWafRateBasedRuleConfigTags2(name, tag1Key, tag1Value, tag2Key, tag2Value string) string {
return fmt.Sprintf(`
resource "aws_waf_rate_based_rule" "wafrule" {
name = "%s"
metric_name = "%s"
rate_key = "IP"
rate_limit = 2000

tags = {
%q = %q
%q = %q
}
}
`, name, name, tag1Key, tag1Value, tag2Key, tag2Value)
}
2 changes: 2 additions & 0 deletions website/docs/r/waf_rate_based_rule.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The following arguments are supported:
* `rate_key` - (Required) Valid value is IP.
* `rate_limit` - (Required) The maximum number of requests, which have an identical value in the field specified by the RateKey, allowed in a five-minute period. Minimum value is 100.
* `predicates` - (Optional) The objects to include in a rule (documented below).
* `tags` - (Optional) Key-value mapping of resource tags

## Nested Blocks

Expand All @@ -69,6 +70,7 @@ See the [WAF Documentation](https://docs.aws.amazon.com/waf/latest/APIReference/
In addition to all arguments above, the following attributes are exported:

* `id` - The ID of the WAF rule.
* `arn` - Amazon Resource Name (ARN)

## Import

Expand Down