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

New Resource: Network Watcher Flow Log #2262

Closed
wants to merge 15 commits into from

Conversation

liemnotliam
Copy link
Contributor

@liemnotliam liemnotliam commented Nov 7, 2018

This PR adds support for a new resource - network watcher flow log.

Addresses issue #1776

Test results:

~/go/src/github.com/terraform-providers/terraform-provider-azurerm on flow-log*
λ TESTARGS="-run TestAccAzureRMNetworkWatcher -count=1" make testacc
==> Checking that code complies with gofmt requirements...
TF_ACC=1 go test $(go list ./... |grep -v 'vendor') -v -run TestAccAzureRMNetworkWatcher -count=1 -timeout 180m -ldflags="-X=github.com/terraform-providers/terraform-provider-azurerm/version.ProviderVersion=acc"
?       github.com/terraform-providers/terraform-provider-azurerm       [no test files]
 === RUN   TestAccAzureRMNetworkWatcher
=== RUN   TestAccAzureRMNetworkWatcher/PacketCapture
=== RUN   TestAccAzureRMNetworkWatcher/PacketCapture/storageAccount
=== RUN   TestAccAzureRMNetworkWatcher/PacketCapture/storageAccountAndLocalDisk
=== RUN   TestAccAzureRMNetworkWatcher/PacketCapture/withFilters
=== RUN   TestAccAzureRMNetworkWatcher/PacketCapture/import
=== RUN   TestAccAzureRMNetworkWatcher/PacketCapture/localDisk
=== RUN   TestAccAzureRMNetworkWatcher/flowLog
=== RUN   TestAccAzureRMNetworkWatcher/flowLog/basic
=== RUN   TestAccAzureRMNetworkWatcher/flowLog/disabled
=== RUN   TestAccAzureRMNetworkWatcher/flowLog/reenabled
=== RUN   TestAccAzureRMNetworkWatcher/flowLog/retentionPolicy
=== RUN   TestAccAzureRMNetworkWatcher/flowLog/updateStorageAccount
=== RUN   TestAccAzureRMNetworkWatcher/flowLog/trafficAnalytics
=== RUN   TestAccAzureRMNetworkWatcher/basic
=== RUN   TestAccAzureRMNetworkWatcher/basic/importComplete
=== RUN   TestAccAzureRMNetworkWatcher/basic/basic
=== RUN   TestAccAzureRMNetworkWatcher/basic/complete
=== RUN   TestAccAzureRMNetworkWatcher/basic/update
=== RUN   TestAccAzureRMNetworkWatcher/basic/disappears
=== RUN   TestAccAzureRMNetworkWatcher/basic/importBasic
--- PASS: TestAccAzureRMNetworkWatcher (4549.48s)
    --- PASS: TestAccAzureRMNetworkWatcher/PacketCapture (3349.09s)
        --- PASS: TestAccAzureRMNetworkWatcher/PacketCapture/storageAccount (654.76s)
        --- PASS: TestAccAzureRMNetworkWatcher/PacketCapture/storageAccountAndLocalDisk (656.54s)
        --- PASS: TestAccAzureRMNetworkWatcher/PacketCapture/withFilters (685.13s)
        --- PASS: TestAccAzureRMNetworkWatcher/PacketCapture/import (672.33s)
        --- PASS: TestAccAzureRMNetworkWatcher/PacketCapture/localDisk (680.32s)
    --- PASS: TestAccAzureRMNetworkWatcher/flowLog (773.12s)
        --- PASS: TestAccAzureRMNetworkWatcher/flowLog/basic (105.67s)
        --- PASS: TestAccAzureRMNetworkWatcher/flowLog/disabled (95.38s)
        --- PASS: TestAccAzureRMNetworkWatcher/flowLog/reenabled (117.66s)
        --- PASS: TestAccAzureRMNetworkWatcher/flowLog/retentionPolicy (114.62s)
        --- PASS: TestAccAzureRMNetworkWatcher/flowLog/updateStorageAccount (138.08s)
        --- PASS: TestAccAzureRMNetworkWatcher/flowLog/trafficAnalytics (201.71s)
    --- PASS: TestAccAzureRMNetworkWatcher/basic (427.27s)
        --- PASS: TestAccAzureRMNetworkWatcher/basic/importComplete (70.20s)
        --- PASS: TestAccAzureRMNetworkWatcher/basic/basic (68.70s)
        --- PASS: TestAccAzureRMNetworkWatcher/basic/complete (68.10s)
        --- PASS: TestAccAzureRMNetworkWatcher/basic/update (84.22s)
        --- PASS: TestAccAzureRMNetworkWatcher/basic/disappears (66.57s)
        --- PASS: TestAccAzureRMNetworkWatcher/basic/importBasic (69.50s)
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm       4549.514s
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/authentication        0.027s [no tests to run]
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure 0.039s [no tests to run]
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/kubernetes    0.014s [no tests to run]
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response      0.028s [no tests to run]
?       github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/set   [no test files]
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress      0.035s [no tests to run]
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate      0.018s [no tests to run]
testing: warning: no tests to run
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils 0.018s [no tests to run]
?       github.com/terraform-providers/terraform-provider-azurerm/version       [no test files]

(fixes #1776)

@ghost ghost added the size/XXL label Nov 7, 2018
Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @liemnotliam,

Thank you for this contribute. In addition to the comments I have left inline I think this makes more sense to be part of the network watcher resource rather than separate.

It's not creating or deleting an actual resource, just configuring an existing one, plus there is only one per network watcher. What do you think?

"workspace_id": {
Type: schema.TypeString,
Required: true,
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we validate the ID here?

}

err = future.WaitForCompletionRef(ctx, client.Client)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor but these lines could be joined:

	if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {

}

err = future.WaitForCompletionRef(ctx, client.Client)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor but these lines could be joined:

	if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {

resource.TestCheckResourceAttrSet(resourceName, "network_security_group_id"),
resource.TestCheckResourceAttrSet(resourceName, "storage_account_id"),
resource.TestCheckResourceAttr(resourceName, "retention_policy.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "retention_policy.0.enabled"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to actually check this value for true/false

resource.TestCheckResourceAttrSet(resourceName, "storage_account_id"),
resource.TestCheckResourceAttr(resourceName, "retention_policy.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "retention_policy.0.enabled"),
resource.TestCheckResourceAttrSet(resourceName, "retention_policy.0.days"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

}

err = future.WaitForCompletionRef(ctx, client.Client)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor but these lines could be joined too

}

_, err = future.Result(client)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor but these lines could be joined too


func testAccAzureRMNetworkWatcherFlowLog_retentionPolicyConfig(rInt int, rString string, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker, but we could use a template for the resources we depend on so shorten these tests

@liemnotliam
Copy link
Contributor Author

Thanks for the comments @katbyte I’ll push out the changes later.

There isn’t a 1-1 relationship between a network watcher and the flow log. A single network watcher in a region can configure multiple flow logs for NSGs in that region.

There’s a 1-1 mapping between an NSG and a flow log, but I didn’t want to embed it in the NSG resource because it uses different clients. I thought it would be more flexible to have the flow log as a separate resource so it’s not too tied down to either network watcher or NSG.

I didn’t go down the route of having multiple flow log blocks within the network watcher resource to match how subnet-vnet, subnet-NSG, subnet-routetable associations are mapped as separate resources. There is a network watcher flow resource ID in Azure if you look deep enough, but it’s not supported in the SDKs as of now.

What are your thoughts?

@ghost ghost added size/XL and removed size/XXL labels Nov 12, 2018
@katbyte
Copy link
Collaborator

katbyte commented Nov 13, 2018

@liemnotliam,

If there can be multiple per network watcher then maybe a list of flow logs would make sense? It seems you always need to pass in a network watcher to the client, and the flow log is associated to that network watcher.

I think having as a separate resource kinda complicated the logic because it is a setting/configured as part of a network watcher, and it can't be deleted. While if it was part of that resource it would just be deleted naturally.

@liemnotliam
Copy link
Contributor Author

Yeah it's possible to have multiple flow logs in a single network watcher resource, but it presents a different set of problems and complexity. It is a separate API call to configure each flow log; there is no function in the SDK to update a network watcher that accepts a list of flow logs. This means that there needs to be extra logic in the resource provider to keep track of what the changes were vs what's deployed in Azure and then create(enable)/delete(disable)/update network watcher flow logs accordingly. A couple of tricky scenarios include:

  • the target NSG changes - need to disable existing flow log before enabling the new one
  • the new config has fewer flow logs - need to figure out which ones were removed from the resource config (I haven't seen a way to do that in Terraform, only to get new vs old values as a whole)

Another reason for having it as a separate resource was to be able to dynamically create multiple flow logs like

resource "azurerm_network_watcher_flow" "test" {
    count = "${length(var.nsgs)}"

    network_security_group_id = "${var.nsgs[count.index]}"

   # ...rest of config
}

It's a minor point as I realise it's possible with the new version of Terraform and HCL to do loops and dynamic blocks within a resource, but that hasn't been released yet..

What are your thoughts @katbyte ? I'm alright with either approach

@ghost ghost removed the waiting-response label Nov 28, 2018
@katbyte
Copy link
Collaborator

katbyte commented Nov 28, 2018

@liemnotliam, I think it should be part of the resource and not separate. Any thoughts on this @tombuildsstuff?

You can see how another resource handles the logic in #2055

@katbyte
Copy link
Collaborator

katbyte commented Dec 20, 2018

@liemnotliam 👋

Just wondering if you are still working on this 🙂

@liemnotliam
Copy link
Contributor Author

liemnotliam commented Jan 10, 2019

@katbyte yes, I'll have time to check this again this/next week, but feel free to add/make changes if you have any 🙂

@ghost ghost removed the waiting-response label Jan 10, 2019
@katbyte katbyte added this to the 1.24.0 milestone Feb 8, 2019

if err := d.Set("traffic_analytics", flattenAzureRmNetworkWatcherFlowLogTrafficAnalytics(fli.FlowAnalyticsConfiguration)); err != nil {
return fmt.Errorf("Error setting `traffic_analytics`: %+v", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the properties block may not necessarily be returned (due to an invalid API response) - could we wrap this in an if statement, e.g.:

if props := fli.FlowKLogProperties; props != nil {
  d.Set("network_security_group_id", props.TargetResourceID)
  d.Set("enabled", props.Enabled)

  if props.StorageID != nil && *props.StorageID != "" {
    d.Set("storage_account_id", props.StorageID)
  }

  if err := d.Set("retention_policy", flattenAzureRmNetworkWatcherFlowLogRetentionPolicy(props.RetentionPolicy)); err != nil {
    return fmt.Errorf("Error setting `retention_policy`: %+v", err)
  }

  if err := d.Set("traffic_analytics", flattenAzureRmNetworkWatcherFlowLogTrafficAnalytics(props.FlowAnalyticsConfiguration)); err != nil {
    return fmt.Errorf("Error setting `traffic_analytics`: %+v", err)
  }
}

func flattenAzureRmNetworkWatcherFlowLogTrafficAnalytics(input *network.TrafficAnalyticsProperties) []interface{} {
if input == nil {
return []interface{}{}
} else if isDefaultDisabledFlowLogTrafficAnalytics(input) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor we could probably combine these e.g.

Suggested change
} else if isDefaultDisabledFlowLogTrafficAnalytics(input) {
if input == nil || isDefaultDisabledFlowLogTrafficAnalytics(input) {
return []interface{}{}

}

result := make(map[string]interface{})
if input != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the changes above, since this is now always covered above, I believe we should be able to remove this if statement?

@tombuildsstuff tombuildsstuff modified the milestones: 1.24.0, 1.25.0 Mar 5, 2019
@tombuildsstuff tombuildsstuff removed this from the v1.25.0 milestone Mar 14, 2019
@katbyte
Copy link
Collaborator

katbyte commented May 12, 2019

I have merged master & fixed the above error. Now the tests fail with:

== RUN   TestAccAzureRMNetworkWatcher
=== RUN   TestAccAzureRMNetworkWatcher/FlowLog
=== RUN   TestAccAzureRMNetworkWatcher/FlowLog/trafficAnalytics
--- FAIL: TestAccAzureRMNetworkWatcher (757.42s)
    --- FAIL: TestAccAzureRMNetworkWatcher/FlowLog (757.42s)
        --- FAIL: TestAccAzureRMNetworkWatcher/FlowLog/trafficAnalytics (757.42s)
            testing.go:568: Step 1 error: errors during apply:

                Error: Error waiting for completion of setting Flow Log Configuration for target "/subscriptions/0000000000000/resourceGroups/acctestRG-549559760496298554/providers/Microsoft.Network/networkSecurityGroups/acctestnsg549559760496298554" (Network Watcher "acctestnw-549559760496298554" / Resource Group "acctestRG-549559760496298554"): Code="InternalServerError" Message="An error occurred." Details=[]

                  on /var/folders/bc/2t9ylvbn4lj1_nzj7bxj2kzc0000gn/T/tf-test693438144/main.tf line 38:
                  (source code not available)

I have opened an issue on the azure sdk as all the parameters look correct.

@katbyte katbyte added the upstream/microsoft Indicates that there's an upstream issue blocking this issue/PR label May 12, 2019
@katbyte katbyte added this to the Blocked milestone May 12, 2019
@BenMitchell1979
Copy link

Just out of curiosity - where are we with this? Currently, I'm having to run a script to configure the FlowLogs post TF Deploy and would love to wrap that into the actual deployment.

@peimanja
Copy link

Just out of curiosity - where are we with this? Currently, I'm having to run a script to configure the FlowLogs post TF Deploy and would love to wrap that into the actual deployment.

It's been only a year and a half! Be patient my friend!

@katbyte
Copy link
Collaborator

katbyte commented May 16, 2019

@BenMitchell1979, @peimanja, see my last comment. The resource simply does not work as is and while i have tried to get it into a usable state there's not much i can do with an "internal sever error" message. Without a reasonable error message from azure that makes sense it is not easy to figure out what we need to do. If you would like to see this resource in terraform please +1 the issue on the SDK as we are currently waiting on microsoft.

Also for what it's worth this PR is only 6 months old, not 18.

@peimanja
Copy link

@BenMitchell1979, @peimanja, see my last comment. The resource simply does not work as is and while i have tried to get it into a usable state there's not much i can do with an "internal sever error" message. Without a reasonable error message from azure that makes sense it is not easy to figure out what we need to do. If you would like to see this resource in terraform please +1 the issue on the SDK as we are currently waiting on microsoft.

Also for what it's worth this PR is only 6 months old, not 18.

Sorry, my bad. Do not get me wrong I am ranting about Microsoft support and poorly API and lots of bugs they introduce with each release. I appreciate people contributing and I see most of the contributors are frustrated. many PRs are hanging around for months. This is just bad ...

@erikpaasonen
Copy link

If you would like to see this resource in terraform please +1 the issue on the SDK as we are currently waiting on microsoft.

@katbyte If you'd be willing to include a link to the respective issue here, our team will add our +1's to it (as many as have access). Thanks!

@katbyte
Copy link
Collaborator

katbyte commented May 16, 2019

@erikpaasonen here it is

@tombuildsstuff
Copy link
Contributor

👋

Since this PR is blocked on the upstream issue, rather than leaving this PR open blocked until that's resolved I'm going to temporarily close this PR for the moment (and assign this to the Blocked milestone). Once the upstream issue has been resolved we'll circle back to this and take another look/get this merged 👍

Thanks!

@adjohns
Copy link

adjohns commented Aug 15, 2019

@tombuildsstuff There has been confirmation that this has been fixed on the Azure Go SDK issue.

@ghost ghost removed the waiting-response label Aug 15, 2019
@tombuildsstuff
Copy link
Contributor

@adjohns thanks, we've been trying to re-run the tests to confirm this is fixed - will update when they've finished :)

@SwayTex
Copy link

SwayTex commented Oct 4, 2019

@adjohns thanks, we've been trying to re-run the tests to confirm this is fixed - will update when they've finished :)

Hi @tombuildsstuff, any news about this? It would be a relief, if it's solved. Big thanks anyway 👍

@tesharp
Copy link
Contributor

tesharp commented Nov 8, 2019

@tombuildsstuff Have the tests finished yet? If so will this be looked at again

katbyte added a commit that referenced this pull request Dec 18, 2019
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 17, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New Resource request: Network Watcher Flow Log
10 participants