Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changelog/13949.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
```release-note:enhancement
resource/aws_ec2_traffic_mirror_filter_rule: Add arn attribute.
```

```release-note:enhancement
resource/aws_ec2_traffic_mirror_filter_rule: Add plan time validation to `destination_port_range.from_port`,
`destination_port_range.to_port`, `source_port_range.from_port`, and `source_port_range.to_port`.
```
46 changes: 33 additions & 13 deletions aws/resource_aws_ec2_traffic_mirror_filter_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand All @@ -21,6 +22,10 @@ func resourceAwsEc2TrafficMirrorFilterRule() *schema.Resource {
State: resourceAwsEc2TrafficMirrorFilterRuleImport,
},
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -42,12 +47,14 @@ func resourceAwsEc2TrafficMirrorFilterRule() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"from_port": {
Type: schema.TypeInt,
Optional: true,
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IsPortNumberOrZero,
},
"to_port": {
Type: schema.TypeInt,
Optional: true,
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IsPortNumberOrZero,
},
},
},
Expand Down Expand Up @@ -80,12 +87,14 @@ func resourceAwsEc2TrafficMirrorFilterRule() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"from_port": {
Type: schema.TypeInt,
Optional: true,
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IsPortNumberOrZero,
},
"to_port": {
Type: schema.TypeInt,
Optional: true,
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IsPortNumberOrZero,
},
},
},
Expand Down Expand Up @@ -162,7 +171,7 @@ func resourceAwsEc2TrafficMirrorFilterRuleRead(d *schema.ResourceData, meta inte
}

if nil == rule {
log.Printf("[WARN] EC2 Traffic Mirror Filter (%s) not found, removing from state", d.Id())
log.Printf("[WARN] EC2 Traffic Mirror Filter Rule (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
Expand All @@ -185,29 +194,40 @@ func resourceAwsEc2TrafficMirrorFilterRuleRead(d *schema.ResourceData, meta inte
return fmt.Errorf("error setting source_port_range: %s", err)
}

arn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: ec2.ServiceName,
Region: meta.(*AWSClient).region,
AccountID: meta.(*AWSClient).accountid,
Resource: fmt.Sprintf("traffic-mirror-filter-rule/%s", d.Id()),
}.String()

d.Set("arn", arn)

return nil
}

func findEc2TrafficMirrorFilterRule(ruleId string, filters []*ec2.TrafficMirrorFilter) (rule *ec2.TrafficMirrorFilterRule) {
log.Printf("[DEBUG] searching %s in %d filters", ruleId, len(filters))
for _, v := range filters {
log.Printf("[DEBUG]: searching filter %s, ingress rule count = %d, egress rule count = %d", *v.TrafficMirrorFilterId, len(v.IngressFilterRules), len(v.EgressFilterRules))
log.Printf("[DEBUG]: searching filter %s, ingress rule count = %d, egress rule count = %d",
aws.StringValue(v.TrafficMirrorFilterId), len(v.IngressFilterRules), len(v.EgressFilterRules))
for _, r := range v.IngressFilterRules {
if *r.TrafficMirrorFilterRuleId == ruleId {
if aws.StringValue(r.TrafficMirrorFilterRuleId) == ruleId {
rule = r
break
}
}
for _, r := range v.EgressFilterRules {
if *r.TrafficMirrorFilterRuleId == ruleId {
if aws.StringValue(r.TrafficMirrorFilterRuleId) == ruleId {
rule = r
break
}
}
}

if nil != rule {
log.Printf("[DEBUG]: Found %s in %s", ruleId, *rule.TrafficDirection)
log.Printf("[DEBUG]: Found %s in %s", ruleId, aws.StringValue(rule.TrafficDirection))
}

return rule
Expand Down
48 changes: 38 additions & 10 deletions aws/resource_aws_ec2_traffic_mirror_filter_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func TestAccAWSEc2TrafficMirrorFilterRule_basic(t *testing.T) {
resourceName := "aws_ec2_traffic_mirror_filter_rule.rule"
resourceName := "aws_ec2_traffic_mirror_filter_rule.test"
dstCidr := "10.0.0.0/8"
srcCidr := "0.0.0.0/0"
ruleNum := 1
Expand All @@ -39,6 +39,7 @@ func TestAccAWSEc2TrafficMirrorFilterRule_basic(t *testing.T) {
Config: testAccEc2TrafficMirrorFilterRuleConfig(dstCidr, srcCidr, action, direction, ruleNum),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEc2TrafficMirrorFilterRuleExists(resourceName),
testAccMatchResourceAttrRegionalARN(resourceName, "arn", ec2.ServiceName, regexp.MustCompile(`traffic-mirror-filter-rule/tmfr-.+`)),
resource.TestMatchResourceAttr(resourceName, "traffic_mirror_filter_id", regexp.MustCompile("tmf-.*")),
resource.TestCheckResourceAttr(resourceName, "destination_cidr_block", dstCidr),
resource.TestCheckResourceAttr(resourceName, "rule_action", action),
Expand Down Expand Up @@ -99,6 +100,34 @@ func TestAccAWSEc2TrafficMirrorFilterRule_basic(t *testing.T) {
})
}

func TestAccAWSEc2TrafficMirrorFilterRule_disappears(t *testing.T) {
resourceName := "aws_ec2_traffic_mirror_filter_rule.test"
dstCidr := "10.0.0.0/8"
srcCidr := "0.0.0.0/0"
ruleNum := 1
action := "accept"
direction := "ingress"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccPreCheckAWSEc2TrafficMirrorFilterRule(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEc2TrafficMirrorFilterRuleDestroy,
Steps: []resource.TestStep{
{
Config: testAccEc2TrafficMirrorFilterRuleConfig(dstCidr, srcCidr, action, direction, ruleNum),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEc2TrafficMirrorFilterRuleExists(resourceName),
testAccCheckResourceDisappears(testAccProvider, resourceAwsEc2TrafficMirrorFilterRule(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckAWSEc2TrafficMirrorFilterRuleExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
Expand Down Expand Up @@ -134,7 +163,7 @@ func testAccCheckAWSEc2TrafficMirrorFilterRuleExists(name string) resource.TestC

var exists bool
for _, rule := range ruleList {
if *rule.TrafficMirrorFilterRuleId == ruleId {
if aws.StringValue(rule.TrafficMirrorFilterRuleId) == ruleId {
exists = true
break
}
Expand All @@ -150,11 +179,11 @@ func testAccCheckAWSEc2TrafficMirrorFilterRuleExists(name string) resource.TestC

func testAccEc2TrafficMirrorFilterRuleConfig(dstCidr, srcCidr, action, dir string, num int) string {
return fmt.Sprintf(`
resource "aws_ec2_traffic_mirror_filter" "filter" {
resource "aws_ec2_traffic_mirror_filter" "test" {
}

resource "aws_ec2_traffic_mirror_filter_rule" "rule" {
traffic_mirror_filter_id = aws_ec2_traffic_mirror_filter.filter.id
resource "aws_ec2_traffic_mirror_filter_rule" "test" {
traffic_mirror_filter_id = aws_ec2_traffic_mirror_filter.test.id
destination_cidr_block = "%s"
rule_action = "%s"
rule_number = %d
Expand All @@ -166,11 +195,10 @@ resource "aws_ec2_traffic_mirror_filter_rule" "rule" {

func testAccEc2TrafficMirrorFilterRuleConfigFull(dstCidr, srcCidr, action, dir, description string, ruleNum, srcPortFrom, srcPortTo, dstPortFrom, dstPortTo, protocol int) string {
return fmt.Sprintf(`
resource "aws_ec2_traffic_mirror_filter" "filter" {
}
resource "aws_ec2_traffic_mirror_filter" "test" {}

resource "aws_ec2_traffic_mirror_filter_rule" "rule" {
traffic_mirror_filter_id = aws_ec2_traffic_mirror_filter.filter.id
resource "aws_ec2_traffic_mirror_filter_rule" "test" {
traffic_mirror_filter_id = aws_ec2_traffic_mirror_filter.test.id
destination_cidr_block = "%s"
rule_action = "%s"
rule_number = %d
Expand Down Expand Up @@ -239,7 +267,7 @@ func testAccCheckAWSEc2TrafficMirrorFilterRuleDestroy(s *terraform.State) error
ruleList = append(ruleList, filter.EgressFilterRules...)

for _, rule := range ruleList {
if *rule.TrafficMirrorFilterRuleId == ruleId {
if aws.StringValue(rule.TrafficMirrorFilterRuleId) == ruleId {
return fmt.Errorf("Rule %s still exists in filter %s", ruleId, filterId)
}
}
Expand Down
1 change: 1 addition & 0 deletions website/docs/index.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ for more information about connecting to alternate AWS endpoints or AWS compatib
- [`aws_ebs_volume` data source](/docs/providers/aws/d/ebs_volume.html)
- [`aws_ec2_capacity_reservation` resource](/docs/providers/aws/r/ec2_capacity_reservation.html)
- [`aws_ec2_client_vpn_endpoint` resource](/docs/providers/aws/r/ec2_client_vpn_endpoint.html)
- [`aws_ec2_traffic_mirror_filter_rule` resource](/docs/providers/aws/r/ec2_traffic_mirror_filter_rule.html)
- [`aws_ec2_traffic_mirror_session` resource](/docs/providers/aws/r/ec2_traffic_mirror_session.html)
- [`aws_ec2_traffic_mirror_target` resource](/docs/providers/aws/r/ec2_traffic_mirror_target.html)
- [`aws_ec2_transit_gateway_route_table` data source](/docs/providers/aws/d/ec2_transit_gateway_route_table.html)
Expand Down
21 changes: 11 additions & 10 deletions website/docs/r/ec2_traffic_mirror_filter_rule.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ resource "aws_ec2_traffic_mirror_filter_rule" "rulein" {

The following arguments are supported:

* `description` - (Optional) A description of the traffic mirror filter rule.
* `description` - (Optional) Description of the traffic mirror filter rule.
* `traffic_mirror_filter_id` - (Required) ID of the traffic mirror filter to which this rule should be added
* `destination_cidr_block` - (Required) The destination CIDR block to assign to the Traffic Mirror rule.
* `destination_port_range` - (Optional) The destination port range. Supported only when the protocol is set to TCP(6) or UDP(17). See Traffic mirror port range documented below
* `protocol` - (Optional) The protocol number, for example 17 (UDP), to assign to the Traffic Mirror rule. For information about the protocol value, see [Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml) on the Internet Assigned Numbers Authority (IANA) website.
* `rule_action` - (Required) The action to take (accept | reject) on the filtered traffic. Valid values are `accept` and `reject`
* `rule_number` - (Required) The number of the Traffic Mirror rule. This number must be unique for each Traffic Mirror rule in a given direction. The rules are processed in ascending order by rule number.
* `source_cidr_block` - (Required) The source CIDR block to assign to the Traffic Mirror rule.
* `source_port_range` - (Optional) The source port range. Supported only when the protocol is set to TCP(6) or UDP(17). See Traffic mirror port range documented below
* `traffic_direction` - (Required) The direction of traffic to be captured. Valid values are `ingress` and `egress`
* `destination_cidr_block` - (Required) Destination CIDR block to assign to the Traffic Mirror rule.
* `destination_port_range` - (Optional) Destination port range. Supported only when the protocol is set to TCP(6) or UDP(17). See Traffic mirror port range documented below
* `protocol` - (Optional) Protocol number, for example 17 (UDP), to assign to the Traffic Mirror rule. For information about the protocol value, see [Protocol Numbers](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml) on the Internet Assigned Numbers Authority (IANA) website.
* `rule_action` - (Required) Action to take (accept | reject) on the filtered traffic. Valid values are `accept` and `reject`
* `rule_number` - (Required) Number of the Traffic Mirror rule. This number must be unique for each Traffic Mirror rule in a given direction. The rules are processed in ascending order by rule number.
* `source_cidr_block` - (Required) Source CIDR block to assign to the Traffic Mirror rule.
* `source_port_range` - (Optional) Source port range. Supported only when the protocol is set to TCP(6) or UDP(17). See Traffic mirror port range documented below
* `traffic_direction` - (Required) Direction of traffic to be captured. Valid values are `ingress` and `egress`

Traffic mirror port range support following attributes:

Expand All @@ -77,7 +77,8 @@ Traffic mirror port range support following attributes:

In addition to all arguments above, the following attributes are exported:

* `id` - The name of the traffic mirror filter rule.
* `arn` - ARN of the traffic mirror filter rule.
* `id` - Name of the traffic mirror filter rule.

## Import

Expand Down