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

Firewall filter rules order #293

Closed
Drygster opened this issue Nov 8, 2023 · 23 comments · Fixed by #314
Closed

Firewall filter rules order #293

Drygster opened this issue Nov 8, 2023 · 23 comments · Fixed by #314
Labels
enhancement New feature or request released

Comments

@Drygster
Copy link

Drygster commented Nov 8, 2023

Hello everyone,

New on terraform, i try to create a Terraform configuration for firewalls who could be apply on fresh firewall installation.

Is your feature request related to a problem? Please describe.
When using the "place_before" parameter, we encountered problem between the new incoming rules who need to be order at the same time.
For example :

resource "routeros_ip_firewall_filter" rule0 { ... #already exist }
resource "routeros_ip_firewall_filter" "rule1" {
  ....
  #place_before = "${data.routeros_firewall.fw.rules[2].id}"
}
resource "routeros_ip_firewall_filter" "rule2" {
  ....
  #place_before = "${data.routeros_firewall.fw.rules[3].id}"
}
resource "routeros_ip_firewall_filter" "rule3" { .... #Already exist }

Describe the solution you'd like
When integrating new rules, the use of "place_before" will be usable directly.
Then, permitting to reapply the configuration on different environment without the need to :
comment "place_before" -> apply a first time -> uncomment -> reapply with the "place_before"

Additional context
Is there a meaning to add a parameter to force the rule order and configure the environment on the first terraform apply ?

@Drygster Drygster added the enhancement New feature or request label Nov 8, 2023
@vaerh
Copy link
Collaborator

vaerh commented Nov 9, 2023

Hi, can you show both terraform scenarios that give not expected behavior? Which can be executed to reproduce the problem.
The main difficulty of using place_before is that it is a standard MT function and it should be used according to the functionality provided by the vendor.

@Drygster
Copy link
Author

Drygster commented Nov 9, 2023

Hello @vaerh,
Thanks for your quick reply. :)
There a better example. ^^
In the context of a new firewall initialise with only a management interface (certificate and CA signed); we like to apply a configuration as following:

variable "rule" {
  type = list(object({
    chain                       = string
    action                      = string
    connection_state   = optional(string)
    in_interface_list    = optional(string, "all")
    out_interface_list = optional(string)
    src_address         = optional(string, "0.0.0.0/0")
    dst_address        = optional(string)
    src_port               = optional(string)
    dst_port               = optional(string)
    protocol               = optional(string)
    comment             = optional(string, "(terraform-defined)")
    log                        = optional(bool, false)
    disabled               = optional(bool, true)
    place_before       = optional(number)
  }))
  default = [
{ chain = "input" ,..., place_before = 1},
{ chain = "input",..., place_before = 2},
...
]}

data "routeros_firewall" "fw" {
  rules {
    filter = {
      chain   = "input"
    }
  }

  rules {
    filter = {
      chain = "forward"
    }
  }

  nat {}
}

locals {
  rule_map = { for idx, rule in var.rule : idx => rule }
}

output "rules" {
  value = [for value in data.routeros_firewall.fw.rules : [value.id, value.src_address]]
}

output "nat" {
  value = [for value in data.routeros_firewall.fw.nat : [value.id, value.comment]]
}

resource "routeros_ip_firewall_filter" "rule" {
  for_each          = local.rule_map
  chain             = each.value.chain
  action            = each.value.action
  comment           = each.value.comment
  log               = each.value.log
  disabled          = each.value.disabled
  connection_state  = each.value.connection_state
  in_interface_list = each.value.in_interface_list
  src_address       = each.value.src_address
  dst_port          = each.value.dst_port
  protocol          = each.value.protocol
  place_before      = "${data.routeros_firewall.fw.rules[each.value.place_before].id}"
}

I'm unsure for the value of the place_before parameter in the resource ( data.routeros_firewall.fw ).
Thus, from my understanding, to use place_before ; it is necessary to have already instantiated rules into the running configuration.

So, to apply this configuration to a new firewall, we'll need to apply the configuration without the place_before parameter and then reapply the rules one by one with the place_before.

That's why, i open this request for a new feature ^^.
Feel free to give any hints or comments if there another possibility :)

Have a nice day.

@vaerh
Copy link
Collaborator

vaerh commented Nov 10, 2023

Yeah, unfortunately that's not a good scenario. On MT, the rules will be created exactly in the sequence in which the REST requests arrive. Parallelism of resource creation > 1 will result in rules being created in a chaotic order. Maybe this discussion will tell you something.
Using the place_before instruction is good for adding new rules in the middle of an existing list, since you need to know the rule sequence numbers in advance.
Unfortunately I don't have a nice recipe to solve this problem.

@rgl
Copy link

rgl commented Nov 17, 2023

For comparison, in ansible, we can set the whole linux iptables firewall rules using a single ansible module as:

    # NB this is equivalent to iptables-apply /etc/iptables/rules.v4.backstage
    - name: Set the iptables rules
      community.general.iptables_state:
        state: restored
        path: /etc/iptables/rules.v4.backstage
      async: "{{ ansible_timeout }}"
      poll: 0
      # NB this is skipped when running in check mode because it requires the
      #    backstage file.
      when: not ansible_check_mode

I think this terraform provider should have a resource that allows us to do the same. That is, declare the desired state using a single resource, which would ensure the rules are applied in one go/transaction and in the order defined in the resource.

IMHO, the existing terraform resources provided by this module are somewhat misleading, because, in practice, the actual router firewall rules are created out of order (using depends_on does not help either), either when you start fresh, or down the line, while you update the firewall rules in the terraform program.

@vaerh
Copy link
Collaborator

vaerh commented Nov 17, 2023

While thinking about the answer, I also considered the option of a resource with a multiple set of rules, but this would entail the impossibility to operate with individual rules and would require significant refactoring.
Perhaps I will make a separate resource for creating rule sets, but once again, editing this resource will lead to deleting the entire set and creating it again.
In the case of ansible everything works well, as it uses a completely different idea of firewall operation.

@rgl
Copy link

rgl commented Nov 17, 2023

@vaerh, that would be nice! if possible, the provider should abort the plan when the user mixes the two resource types.

The entire rule set apply should be transactional and idempotent. if that's not possible to implement with the existing mikrotik api, we should try to plea mikrotik to implement it. mainly, because implementing this is tricky (e.g. deleting the firewall rules and creating them again leaves a open window of time without an active firewall; also, while deleting the firewall rules you have to be careful for not blocking the active provider connection to the mikrotik api; also, "Here be dragons").

@vaerh
Copy link
Collaborator

vaerh commented Nov 17, 2023

I'm glad we're both presenting the dubious benefit of recreating firewall rules on the fly.
But I'm going to give PoC a try.
If you have the patience and desire, try writing to MT tech support. My communication with them has been unsuccessful.

@rgl
Copy link

rgl commented Nov 18, 2023

from the mikrotik forums, it seems there's no way to do this in a elegant way, nor it seemed to peek mikrotik interest in implementing that feature. so I think I will not buy Mirotik hardware at all.

FWIW, I've found these references related to the firewall rules:

@xilmen
Copy link

xilmen commented Nov 19, 2023

from the mikrotik forums, it seems there's no way to do this in a elegant way, nor it seemed to peek mikrotik interest in implementing that feature. so I think I will not buy Mirotik hardware at all.

FWIW, I've found these references related to the firewall rules:

* [Transactions [Feature Request]](https://forum.mikrotik.com/viewtopic.php?t=125205)

* [How to write idempotent script](https://forum.mikrotik.com/viewtopic.php?t=182961)

* https://wiki.mikrotik.com/wiki/Manual:Configuration_Management

Do you know which fw hardware is properly implemented with tf?

@vaerh
Copy link
Collaborator

vaerh commented Nov 19, 2023

@Drygster I have a concept for a firewall rule sorter, but in keeping with MT tradition it doesn't always work the way I envision. Sometimes the rules are sorted, sometimes not. Is there any way to test the module without modifying the main provider?

@vaerh
Copy link
Collaborator

vaerh commented Nov 19, 2023

Do you know which fw hardware is properly implemented with tf?

A number of vendors support their TF providers, you can see if they are available in the registry

@Drygster
Copy link
Author

Hello @vaerh,

"Sometimes the rules are sorted, sometimes not. Is there any way to test the module without modifying the main provider?"
If you want to operate some tests i have a small environment base on CHR (Cloud Hosted Router).
I can snapshot it and try some tests.

@vaerh
Copy link
Collaborator

vaerh commented Nov 19, 2023

@Drygster What OS do you use? I will make a provider build for you.

I'm also debugging the functionality on CHR, but maybe you'll do much better.

@vaerh
Copy link
Collaborator

vaerh commented Nov 19, 2023

~/.terraformrc

provider_installation {
  dev_overrides {
    "registry.terraform.io/terraform-routeros/routeros" = "/path-to-directory-w-provider/terraform-provider-routeros"
  }
}

test.tf

variable "rule" {
  type = list(object({
    chain              = string
    action             = string
    connection_state   = optional(string)
    in_interface_list  = optional(string, "all")
    out_interface_list = optional(string)
    src_address        = optional(string, "0.0.0.0/0")
    dst_address        = optional(string)
    src_port           = optional(string)
    dst_port           = optional(string)
    protocol           = optional(string)
    comment            = optional(string, "(terraform-defined)")
    log                = optional(bool, false)
    disabled           = optional(bool, true)
    position           = optional(number)
  }))

  default = [
    { chain = "input", action = "accept", position = 00 },
    { chain = "input", action = "accept", position = 01 },
    { chain = "input", action = "accept", position = 02 },
    { chain = "input", action = "accept", position = 03 },
    { chain = "input", action = "accept", position = 04 },
    { chain = "input", action = "accept", position = 05 },
    { chain = "input", action = "accept", position = 06 },
    { chain = "input", action = "accept", position = 07 },
    { chain = "input", action = "accept", position = 08 },
    { chain = "input", action = "accept", position = 09 },
    { chain = "input", action = "accept", position = 10 },
    { chain = "input", action = "accept", position = 11 },
    { chain = "input", action = "accept", position = 12 },
    { chain = "input", action = "accept", position = 13 },
    { chain = "input", action = "accept", position = 14 },
    { chain = "input", action = "accept", position = 15 },
    { chain = "input", action = "accept", position = 16 },
    { chain = "input", action = "accept", position = 17 },
    { chain = "input", action = "accept", position = 18 },
    { chain = "input", action = "accept", position = 19 },
    { chain = "input", action = "accept", position = 20 },
    { chain = "input", action = "accept", position = 21 },
    { chain = "input", action = "accept", position = 22 },
    { chain = "input", action = "accept", position = 23 },
    { chain = "input", action = "accept", position = 24 },
    { chain = "input", action = "accept", position = 25 },
    { chain = "input", action = "accept", position = 26 },
    { chain = "input", action = "accept", position = 27 },
    { chain = "input", action = "accept", position = 28 },
    { chain = "input", action = "accept", position = 29 },
    { chain = "input", action = "accept", position = 30 },
    { chain = "input", action = "accept", position = 31 },
  ]
}

locals {
  rule_map = { for idx, rule in var.rule : idx => rule }
}

resource "routeros_ip_firewall_filter" "rule" {
  for_each          = local.rule_map
  chain             = each.value.chain
  action            = each.value.action
  comment           = each.value.position
  log               = each.value.log
  disabled          = each.value.disabled
  connection_state  = each.value.connection_state
  in_interface_list = each.value.in_interface_list
  src_address       = each.value.src_address
  dst_port          = each.value.dst_port
  protocol          = each.value.protocol
  position          = each.value.position
}

resource "routeros_move_items" "fw_rules" {
  resource_name = "routeros_ip_firewall_filter"
  move          = zipmap(values(routeros_ip_firewall_filter.rule)[*].position, values(routeros_ip_firewall_filter.rule)[*].id)
  depends_on    = [routeros_ip_firewall_filter.rule]
}

If you use part of your original configuration for testing, it would be very interesting to know the result.

@Drygster
Copy link
Author

Drygster commented Nov 19, 2023

@Drygster What OS do you use? I will make a provider build for you.

I'm also debugging the functionality on CHR, but maybe you'll do much better.

NAME="Rocky Linux"
VERSION="9.2 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.2"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.2 (Blue Onyx)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:9::baseos"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
SUPPORT_END="2032-05-31"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"
ROCKY_SUPPORT_PRODUCT_VERSION="9.2"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.2"

@vaerh
Copy link
Collaborator

vaerh commented Nov 19, 2023

Use linux-amd64.zip

@Drygster
Copy link
Author

Hello @vaerh,
I try to apply with the new provider.
I erase the tf_state and all the object but didn't seems to apply correctly at the moment.
I obtain the attach result.
Screenshot 2023-11-21 at 14 20 13
I add in the rule comment the Rule [Rule number] to follow the main differences.

@vaerh
Copy link
Collaborator

vaerh commented Nov 21, 2023

@Drygster, to close this issue... Please also delete the rules and the state file and execute the plan that way:

TF_LOG=debug ROS_LOG_COLOR=1 terraform ...

From the output I will only be interested in the last green lines that have "/move" in them, and also make the rules print from the MT console: /ip/firewall/filter/print show-ids

@Drygster
Copy link
Author

Drygster commented Nov 21, 2023

Helo @vaerh,

2023-11-21T20:04:15.796+0100 [DEBUG] routeros_ip_firewall_filter.rules["2"]: applying the planned Create change
routeros_ip_firewall_filter.rules["0"]: Creating...
2023-11-21T20:04:15.797+0100 [INFO]  Starting apply for routeros_ip_firewall_filter.rules["0"]
2023-11-21T20:04:15.797+0100 [DEBUG] routeros_ip_firewall_filter.rules["0"]: applying the planned Create change
2023-11-21T20:04:15.804+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"action":"accept","address-list-timeout":"none-dynamic","chain":"input","comment":"Rule 3 - udp 8200,8202","disabled":"no","dst-port":"8200,8202","in-interface-list":"WAN-TV","log":"no","protocol":"udp","src-address":"0.0.0.0/0"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:15.804+0100"
2023-11-21T20:04:15.804+0100 [DEBUG] provider.terraform-provider-routeros: PUT request URL:  https://172.19.3.1/rest/ip/firewall/filter: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:15.804+0100"
2023-11-21T20:04:15.807+0100 [WARN]  Provider "registry.terraform.io/terraform-routeros/routeros" produced an invalid plan for routeros_ip_firewall_filter.rules["1"], but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:
      - .address_list_timeout: planned value cty.StringVal("none-dynamic") for a non-computed attribute
routeros_ip_firewall_filter.rules["1"]: Creating...
2023-11-21T20:04:15.808+0100 [INFO]  Starting apply for routeros_ip_firewall_filter.rules["1"]
2023-11-21T20:04:15.808+0100 [DEBUG] routeros_ip_firewall_filter.rules["1"]: applying the planned Create change
2023-11-21T20:04:15.811+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"action":"accept","address-list-timeout":"none-dynamic","chain":"input","comment":"Rule 0 - established,related","connection-state":"established,related","disabled":"no","in-interface-list":"all","log":"no","src-address":"0.0.0.0/0"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:15.810+0100"
2023-11-21T20:04:15.811+0100 [DEBUG] provider.terraform-provider-routeros: PUT request URL:  https://172.19.3.1/rest/ip/firewall/filter: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:15.810+0100"
2023-11-21T20:04:15.815+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"action":"drop","address-list-timeout":"none-dynamic","chain":"input","comment":"Rule 5 - all-wan","disabled":"no","in-interface-list":"all-wan","log":"no","src-address":"0.0.0.0/0"}: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:15.813+0100"
2023-11-21T20:04:15.815+0100 [DEBUG] provider.terraform-provider-routeros: PUT request URL:  https://172.19.3.1/rest/ip/firewall/filter: @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure timestamp="2023-11-21T20:04:15.815+0100"
2023-11-21T20:04:15.820+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"action":"drop","address-list-timeout":"none-dynamic","chain":"input","comment":"Rule 1 - invalid,untracked","connection-state":"invalid,untracked","disabled":"no","in-interface-list":"all","log":"no","src-address":"0.0.0.0/0"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:15.820+0100"
2023-11-21T20:04:15.821+0100 [DEBUG] provider.terraform-provider-routeros: PUT request URL:  https://172.19.3.1/rest/ip/firewall/filter: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:15.821+0100"
2023-11-21T20:04:15.822+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"action":"accept","address-list-timeout":"none-dynamic","chain":"input","comment":"Rule 2 - igmp","disabled":"no","in-interface-list":"WAN-TV","log":"no","protocol":"igmp","src-address":"0.0.0.0/0"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:15.820+0100"
2023-11-21T20:04:15.822+0100 [DEBUG] provider.terraform-provider-routeros: PUT request URL:  https://172.19.3.1/rest/ip/firewall/filter: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:15.822+0100"
2023-11-21T20:04:15.823+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"action":"accept","address-list-timeout":"none-dynamic","chain":"input","comment":"Rule 4 - established,related","connection-state":"established,related","disabled":"no","in-interface-list":"all-wan","log":"no","src-address":"0.0.0.0/0"}: @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure timestamp="2023-11-21T20:04:15.815+0100"
2023-11-21T20:04:15.823+0100 [DEBUG] provider.terraform-provider-routeros: PUT request URL:  https://172.19.3.1/rest/ip/firewall/filter: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:15.823+0100"
2023-11-21T20:04:16.715+0100 [DEBUG] provider.terraform-provider-routeros: response body: {".id":"*2E","action":"accept","bytes":"0","chain":"input","comment":"Rule 0 - established,related","connection-state":"established,related","disabled":"false","dynamic":"false","in-interface-list":"all","invalid":"true","log":"false","packets":"0","src-address":"0.0.0.0/0"}: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:16.714+0100"
2023-11-21T20:04:16.715+0100 [DEBUG] provider.terraform-provider-routeros: response body: {".id":"*2D","action":"drop","bytes":"0","chain":"input","comment":"Rule 5 - all-wan","disabled":"false","dynamic":"false","in-interface-list":"all-wan","invalid":"false","log":"false","packets":"0","src-address":"0.0.0.0/0"}: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:16.714+0100"
routeros_ip_firewall_filter.rules["0"]: Creation complete after 1s [id=*2E]
2023-11-21T20:04:16.718+0100 [DEBUG] State storage *remote.State declined to persist a state snapshot
routeros_ip_firewall_filter.rules["5"]: Creation complete after 1s [id=*2D]
2023-11-21T20:04:16.720+0100 [DEBUG] State storage *remote.State declined to persist a state snapshot
2023-11-21T20:04:16.778+0100 [DEBUG] provider.terraform-provider-routeros: response body: {".id":"*2F","action":"accept","bytes":"0","chain":"input","comment":"Rule 3 - udp 8200,8202","disabled":"false","dst-port":"8200,8202","dynamic":"false","in-interface-list":"WAN-TV","invalid":"true","log":"false","packets":"0","protocol":"udp","src-address":"0.0.0.0/0"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.778+0100"
2023-11-21T20:04:16.779+0100 [DEBUG] provider.terraform-provider-routeros: response body: {".id":"*30","action":"drop","bytes":"0","chain":"input","comment":"Rule 1 - invalid,untracked","connection-state":"invalid,untracked","disabled":"false","dynamic":"false","in-interface-list":"all","invalid":"true","log":"false","packets":"0","src-address":"0.0.0.0/0"}: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:16.779+0100"
routeros_ip_firewall_filter.rules["3"]: Creation complete after 1s [id=*2F]
2023-11-21T20:04:16.781+0100 [DEBUG] State storage *remote.State declined to persist a state snapshot
2023-11-21T20:04:16.782+0100 [DEBUG] provider.terraform-provider-routeros: response body: {".id":"*32","action":"accept","bytes":"0","chain":"input","comment":"Rule 4 - established,related","connection-state":"established,related","disabled":"false","dynamic":"false","in-interface-list":"all-wan","invalid":"true","log":"false","packets":"0","src-address":"0.0.0.0/0"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.782+0100"
routeros_ip_firewall_filter.rules["1"]: Creation complete after 1s [id=*30]
2023-11-21T20:04:16.783+0100 [DEBUG] State storage *remote.State declined to persist a state snapshot
2023-11-21T20:04:16.783+0100 [DEBUG] provider.terraform-provider-routeros: response body: {".id":"*31","action":"accept","bytes":"0","chain":"input","comment":"Rule 2 - igmp","disabled":"false","dynamic":"false","in-interface-list":"WAN-TV","invalid":"true","log":"false","packets":"0","protocol":"igmp","src-address":"0.0.0.0/0"}: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:16.783+0100"
routeros_ip_firewall_filter.rules["2"]: Creation complete after 1s [id=*31]
2023-11-21T20:04:16.786+0100 [DEBUG] State storage *remote.State declined to persist a state snapshot
routeros_ip_firewall_filter.rules["4"]: Creation complete after 1s [id=*32]
2023-11-21T20:04:16.787+0100 [DEBUG] State storage *remote.State declined to persist a state snapshot
routeros_move_items.movement: Creating...
2023-11-21T20:04:16.801+0100 [INFO]  Starting apply for routeros_move_items.movement
2023-11-21T20:04:16.805+0100 [DEBUG] routeros_move_items.movement: applying the planned Create change
2023-11-21T20:04:16.807+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"destination":"0","numbers":"*2E"}: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:16.806+0100"
2023-11-21T20:04:16.807+0100 [DEBUG] provider.terraform-provider-routeros: POST request URL:  https://172.19.3.1/rest/ip/firewall/filter/move: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.807+0100"
2023-11-21T20:04:16.809+0100 [DEBUG] provider.terraform-provider-routeros: response body: []: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.809+0100"
2023-11-21T20:04:16.825+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"destination":"1","numbers":"*30"}: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:16.825+0100"
2023-11-21T20:04:16.825+0100 [DEBUG] provider.terraform-provider-routeros: POST request URL:  https://172.19.3.1/rest/ip/firewall/filter/move: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.825+0100"
2023-11-21T20:04:16.827+0100 [DEBUG] provider.terraform-provider-routeros: response body: []: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.827+0100"
2023-11-21T20:04:16.842+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"destination":"2","numbers":"*31"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.842+0100"
2023-11-21T20:04:16.842+0100 [DEBUG] provider.terraform-provider-routeros: POST request URL:  https://172.19.3.1/rest/ip/firewall/filter/move: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.842+0100"
2023-11-21T20:04:16.845+0100 [DEBUG] provider.terraform-provider-routeros: response body: []: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.845+0100"
2023-11-21T20:04:16.861+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"destination":"3","numbers":"*2F"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.860+0100"
2023-11-21T20:04:16.861+0100 [DEBUG] provider.terraform-provider-routeros: POST request URL:  https://172.19.3.1/rest/ip/firewall/filter/move: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:16.860+0100"
2023-11-21T20:04:16.863+0100 [DEBUG] provider.terraform-provider-routeros: response body: []: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.863+0100"
2023-11-21T20:04:16.878+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"destination":"4","numbers":"*32"}: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:16.878+0100"
2023-11-21T20:04:16.879+0100 [DEBUG] provider.terraform-provider-routeros: POST request URL:  https://172.19.3.1/rest/ip/firewall/filter/move: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:16.878+0100"
2023-11-21T20:04:17.069+0100 [DEBUG] provider.terraform-provider-routeros: response body: []: @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure timestamp="2023-11-21T20:04:17.069+0100"
2023-11-21T20:04:17.085+0100 [DEBUG] provider.terraform-provider-routeros: request body:  {"destination":"5","numbers":"*2D"}: tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros timestamp="2023-11-21T20:04:17.084+0100"
2023-11-21T20:04:17.085+0100 [DEBUG] provider.terraform-provider-routeros: POST request URL:  https://172.19.3.1/rest/ip/firewall/filter/move: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:17.084+0100"
2023-11-21T20:04:17.087+0100 [DEBUG] provider.terraform-provider-routeros: response body: []: @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 timestamp="2023-11-21T20:04:17.087+0100"
2023-11-21T20:04:17.102+0100 [DEBUG] provider.terraform-provider-routeros: GET request URL:  https://172.19.3.1/rest/ip/firewall/filter: tf_rpc=Configure @caller=/home/z/GolandProjects/terraform-provider-routeros/routeros/log.go:27 @module=routeros tf_provider_addr=terraform-routeros/routeros tf_req_id=ca5929d5-4ae6-78eb-88de-1bb08094b6be timestamp="2023-11-21T20:04:17.102+0100"
2023-11-21T20:04:17.106+0100 [WARN]  Provider "provider[\"registry.terraform.io/terraform-routeros/routeros\"]" produced an unexpected new value for routeros_move_items.movement, but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:
      - .move["0"]: was cty.StringVal("*2E"), but now cty.StringVal("*2F")
      - .move["2"]: was cty.StringVal("*31"), but now cty.StringVal("*2E")
      - .move["3"]: was cty.StringVal("*2F"), but now cty.StringVal("*2D")
      - .move["5"]: was cty.StringVal("*2D"), but now cty.StringVal("*31")
[admin@MikroTik] > /ip/firewall/filter/print show-ids
Flags: X - disabled, I - invalid; D - dynamic 
*2F    ;;; Rule 3 - udp 8200,8202
      chain=input action=accept protocol=udp src-address=0.0.0.0/0 in-interface-list=WAN-TV dst-port=8200,8202 log=no 

*30    ;;; Rule 1 - invalid,untracked
      chain=input action=drop connection-state=invalid,untracked src-address=0.0.0.0/0 in-interface-list=all log=no 

*2E    ;;; Rule 0 - established,related
      chain=input action=accept connection-state=established,related src-address=0.0.0.0/0 in-interface-list=all log=no 

*2D    ;;; Rule 5 - all-wan
      chain=input action=drop src-address=0.0.0.0/0 in-interface-list=all-wan log=no 

*32    ;;; Rule 4 - established,related
      chain=input action=accept connection-state=established,related src-address=0.0.0.0/0 in-interface-list=all-wan log=no 

*31    ;;; Rule 2 - igmp
      chain=input action=accept protocol=igmp src-address=0.0.0.0/0 in-interface-list=WAN-TV log=no 

@vaerh
Copy link
Collaborator

vaerh commented Nov 21, 2023

Thank you! Moving the rules unfortunately doesn't work. Looks like an internal ROS error. Rules are moved from the console in a chaotic way. So this implementation will not help us.

@vaerh
Copy link
Collaborator

vaerh commented Nov 23, 2023

After a number of experiments on this issue, I can state a disappointing result: the creation of rule groups requires a major redesign of the main data serializer, which is used in all provider resources.
There is also a problem that will not be solved in any case, TF logic will not support and control the integrity of single rules, as well as their mutual location. Thus, if after adding the initialization list of rules there will be a change of their order (for example, through Winbox), it will lead to uncertainty, which can not be solved by TF.
If anyone wants to help with this problem, I would like to ask MT support to fix the "move" functionality within the firewall.
It is not working when using REST API to create 30 rules in random order and sort them also using REST API move command.

vaerh added a commit that referenced this issue Dec 6, 2023
@vaerh
Copy link
Collaborator

vaerh commented Dec 6, 2023

@Drygster
Please test after the release.
The example has also been updated.

@vaerh vaerh closed this as completed in #314 Dec 6, 2023
vaerh added a commit that referenced this issue Dec 6, 2023
* fix: Firewall filter rules order
Fixes  #293
Thanks to @Toalaah

* fix: Resource path
@vaerh
Copy link
Collaborator

vaerh commented Dec 6, 2023

🎉 This issue has been resolved in version 1.27.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants