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

ec_deployment_traffic_filter: Support Azure PL #340

Merged
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
3 changes: 3 additions & 0 deletions .changelog/340.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/ec_deployment_traffic_filter: Add support for Azure Private Link traffic rules.
```
53 changes: 51 additions & 2 deletions docs/resources/ec_deployment_traffic_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Provides an Elastic Cloud traffic filter resource, which allows traffic filter r

## Example Usage

### IP type

```hcl
data "ec_stack" "latest" {
version_regex = "latest"
Expand Down Expand Up @@ -47,12 +49,57 @@ resource "ec_deployment_traffic_filter" "example" {
}
```

### Azure Private Link type

```hcl
locals {
region = azure-australiaeast
}

data "ec_stack" "latest" {
version_regex = "latest"
region = local.region
}

# Create an Elastic Cloud deployment
resource "ec_deployment" "example_minimal" {
# Optional name.
name = "my_example_deployment"

# Mandatory fields
region = local.region
version = data.ec_stack.latest.version
deployment_template_id = "aws-io-optimized-v2"

traffic_filter = [
ec_deployment_traffic_filter.azure.id
]

# Use the deployment template defaults
elasticsearch {}

kibana {}
}

resource "ec_deployment_traffic_filter" "azure" {
name = "my traffic filter name"
region = local.region
type = "azure_private_endpoint"

rule {
azure_endpoint_name = "my-azure-pl"
azure_endpoint_guid = "78c64959-fd88-41cc-81ac-1cfcdb1ac32e"
}
}

```

## Argument Reference

The following arguments are supported:

* `name` - (Required) Name of the ruleset.
* `type` - (Required) Type of the ruleset. It can be `"ip"` or `"vpce"`.
* `type` - (Required) Type of the ruleset. It can be `"ip"`, `"vpce"` or `"azure_private_endpoint"`.
* `region` - (Required) Filter region, the ruleset can only be attached to deployments in the specific region.
* `rule` (Required) Rule block, which can be specified multiple times for multiple rules.
* `include_by_default` - (Optional) To automatically include the ruleset in the new deployments. Defaults to `false`.
Expand All @@ -62,8 +109,10 @@ The following arguments are supported:

The `rule` block supports the following configuration options:

* `source` - (Required) Source type, `"ip"` or `"vpce"`, from which the ruleset accepts traffic.
* `source` - (Optional) traffic filter source: IP address, CIDR mask, or VPC endpoint ID, **only required** when the type is not `"azure_private_endpoint"`.
* `description` - (Optional) Description of this individual rule.
* `azure_endpoint_name` - (Optional) Azure endpoint name. Only applicable when the ruleset type is set to `"azure_private_endpoint"`.
* `azure_endpoint_guid` - (Optional) Azure endpoint GUID. Only applicable when the ruleset type is set to `"azure_private_endpoint"`.

## Attributes Reference

Expand Down
25 changes: 25 additions & 0 deletions ec/acc/deployment_traffic_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package acc
import (
"fmt"
"os"
"regexp"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
Expand Down Expand Up @@ -88,6 +89,30 @@ func TestAccDeploymentTrafficFilter_basic(t *testing.T) {
})
}

func TestAccDeploymentTrafficFilter_azure(t *testing.T) {
resName := "ec_deployment_traffic_filter.azure"
randomName := prefix + acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
startCfg := "testdata/deployment_traffic_filter_azure.tf"
cfg := fixtureAccDeploymentTrafficFilterResourceBasic(t, startCfg, randomName, "azure-australiaeast")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: testAccProviderFactory,
CheckDestroy: testAccDeploymentTrafficFilterDestroy,
Steps: []resource.TestStep{
{
Config: cfg,
Check: checkBasicDeploymentTrafficFilterResource(resName, randomName,
resource.TestCheckResourceAttr(resName, "include_by_default", "false"),
resource.TestCheckResourceAttr(resName, "type", "azure_private_endpoint"),
resource.TestCheckResourceAttr(resName, "rule.#", "1"),
),
ExpectError: regexp.MustCompile(`.*traffic_filter.azure_private_link_connection_not_found.*`),
},
},
})
}

func fixtureAccDeploymentTrafficFilterResourceBasic(t *testing.T, fileName, name, region string) string {
t.Helper()
b, err := os.ReadFile(fileName)
Expand Down
10 changes: 10 additions & 0 deletions ec/acc/testdata/deployment_traffic_filter_azure.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "ec_deployment_traffic_filter" "azure" {
name = "%s"
region = "%s"
type = "azure_private_endpoint"

rule {
azure_endpoint_name = "my-azure-pl"
azure_endpoint_guid = "78c64959-fd88-41cc-81ac-1cfcdb1ac32e"
}
}
8 changes: 8 additions & 0 deletions ec/ecresource/trafficfilterresource/expanders.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ func expandModel(d *schema.ResourceData) *models.TrafficFilterRulesetRequest {
rule.Description = val.(string)
}

if val, ok := m["azure_endpoint_name"]; ok {
rule.AzureEndpointName = val.(string)
}

if val, ok := m["azure_endpoint_guid"]; ok {
rule.AzureEndpointGUID = val.(string)
}

request.Rules = append(request.Rules, &rule)
}

Expand Down
29 changes: 29 additions & 0 deletions ec/ecresource/trafficfilterresource/expanders_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,35 @@ func Test_expandModel(t *testing.T) {
},
},
},
{
name: "parses an Azure privatelink resource",
args: args{d: util.NewResourceData(t, util.ResDataParams{
ID: "some-random-id",
State: map[string]interface{}{
"name": "my traffic filter",
"type": "azure_private_endpoint",
"include_by_default": false,
"region": "azure-australiaeast",
"rule": []interface{}{map[string]interface{}{
"azure_endpoint_guid": "1231312-1231-1231-1231-1231312",
"azure_endpoint_name": "my-azure-pl",
}},
},
Schema: newSchema(),
})},
want: &models.TrafficFilterRulesetRequest{
Name: ec.String("my traffic filter"),
Type: ec.String("azure_private_endpoint"),
IncludeByDefault: ec.Bool(false),
Region: ec.String("azure-australiaeast"),
Rules: []*models.TrafficFilterRule{
{
AzureEndpointGUID: "1231312-1231-1231-1231-1231312",
AzureEndpointName: "my-azure-pl",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
12 changes: 11 additions & 1 deletion ec/ecresource/trafficfilterresource/flatteners.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ func flattenRules(rules []*models.TrafficFilterRule) *schema.Set {
result := schema.NewSet(trafficFilterRuleHash, []interface{}{})
for _, rule := range rules {
var m = make(map[string]interface{})
m["source"] = rule.Source
if rule.Source != "" {
m["source"] = rule.Source
}

if rule.Description != "" {
m["description"] = rule.Description
Expand All @@ -66,6 +68,14 @@ func flattenRules(rules []*models.TrafficFilterRule) *schema.Set {
m["id"] = rule.ID
}

if rule.AzureEndpointGUID != "" {
m["azure_endpoint_guid"] = rule.AzureEndpointGUID
}

if rule.AzureEndpointName != "" {
m["azure_endpoint_name"] = rule.AzureEndpointName
}

result.Add(m)
}

Expand Down
36 changes: 36 additions & 0 deletions ec/ecresource/trafficfilterresource/flatteners_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,24 @@ func Test_modelToState(t *testing.T) {
},
Schema: newSchema(),
})

azurePLSchemaArg := schema.TestResourceDataRaw(t, newSchema(), nil)
azurePLSchemaArg.SetId("some-random-id")

azurePLRemoteState := models.TrafficFilterRulesetInfo{
ID: ec.String("some-random-id"),
Name: ec.String("my traffic filter"),
Type: ec.String("azure_private_endpoint"),
IncludeByDefault: ec.Bool(false),
Region: ec.String("azure-australiaeast"),
Rules: []*models.TrafficFilterRule{
{
AzureEndpointGUID: "1231312-1231-1231-1231-1231312",
AzureEndpointName: "my-azure-pl",
},
},
}

type args struct {
d *schema.ResourceData
res *models.TrafficFilterRulesetInfo
Expand All @@ -155,6 +173,24 @@ func Test_modelToState(t *testing.T) {
args: args{d: trafficFilterSchemaArgMultipleRWithDesc, res: &remoteStateMultipleRulesWithDesc},
want: wantTrafficFilterMultipleRWithDesc,
},
{
name: "flattens the resource with multiple rules with descriptions",
args: args{d: azurePLSchemaArg, res: &azurePLRemoteState},
want: util.NewResourceData(t, util.ResDataParams{
ID: "some-random-id",
State: map[string]interface{}{
"name": "my traffic filter",
"type": "azure_private_endpoint",
"include_by_default": false,
"region": "azure-australiaeast",
"rule": []interface{}{map[string]interface{}{
"azure_endpoint_guid": "1231312-1231-1231-1231-1231312",
"azure_endpoint_name": "my-azure-pl",
}},
},
Schema: newSchema(),
}),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
28 changes: 24 additions & 4 deletions ec/ecresource/trafficfilterresource/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func newSchema() map[string]*schema.Schema {
},
"type": {
Type: schema.TypeString,
Description: `Required type of the ruleset ("ip" or "vpce")`,
Description: `Required type of the ruleset ("ip", "vpce" or "azure_private_endpoint")`,
Required: true,
},
"region": {
Expand All @@ -51,8 +51,8 @@ func newSchema() map[string]*schema.Schema {
Schema: map[string]*schema.Schema{
"source": {
Type: schema.TypeString,
Description: "Required traffic filter source: IP address, CIDR mask, or VPC endpoint ID",
Required: true,
Description: "Required traffic filter source: IP address, CIDR mask, or VPC endpoint ID, not required when the type is azure_private_endpoint",
Optional: true,
},

"description": {
Expand All @@ -61,6 +61,18 @@ func newSchema() map[string]*schema.Schema {
Optional: true,
},

"azure_endpoint_name": {
Type: schema.TypeString,
Description: "Optional Azure endpoint name",
Optional: true,
},

"azure_endpoint_guid": {
Type: schema.TypeString,
Description: "Optional Azure endpoint GUID",
Optional: true,
},

"id": {
Type: schema.TypeString,
Description: "Computed rule ID",
Expand All @@ -87,9 +99,17 @@ func newSchema() map[string]*schema.Schema {
func trafficFilterRuleHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(m["source"].(string))
if m["source"] != nil {
buf.WriteString(m["source"].(string))
}
if m["description"] != nil {
buf.WriteString(m["description"].(string))
}
if m["azure_endpoint_name"] != nil {
buf.WriteString(m["azure_endpoint_name"].(string))
}
if m["azure_endpoint_guid"] != nil {
buf.WriteString(m["azure_endpoint_guid"].(string))
}
return schema.HashString(buf.String())
}