From 9141c9a3c840896b99db111f32efec7810dd7df9 Mon Sep 17 00:00:00 2001 From: Bryan Dady Date: Fri, 14 Jun 2024 09:54:47 -0600 Subject: [PATCH] feat! remove firewall rules (#43) * refactor(firewall): implement new 'ruleset' resource * fix(main): typo in argo_enabled * fix: remove deprecated firewall resources * example: update with deprecated firewall resources removed * docs: update terraform.md and README * feat(versions): bump cloudflare provider to >= 4.0 * example: update req provider and outputs --- .gitignore | 3 ++ README.md | 63 +++++++++++------------------------ docs/terraform.md | 11 ++---- examples/complete/main.tf | 8 ----- examples/complete/outputs.tf | 10 ------ examples/complete/versions.tf | 2 +- firewall.tf | 31 ----------------- main.tf | 8 ++--- outputs.tf | 10 ------ variables.tf | 25 -------------- versions.tf | 2 +- 11 files changed, 31 insertions(+), 142 deletions(-) delete mode 100644 firewall.tf diff --git a/.gitignore b/.gitignore index 1c768ad..7b4dd0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # Local .terraform directories **/.terraform/* +# Local .terraform lock file +**/.terraform.lock.hcl + # .tfstate files *.tfstate *.tfstate.* diff --git a/README.md b/README.md index fab128a..ba978f7 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,6 @@ Terraform module to provision a CloudFlare zone with: DNS records, Argo, Firewall filters and rules. - > [!TIP] -> #### 👽 Use Atmos with Terraform +> +> ### 👽 Use Atmos with Terraform +> > Cloud Posse uses [`atmos`](https://atmos.tools) to easily orchestrate multiple environments using Terraform.
> Works with [Github Actions](https://atmos.tools/integrations/github-actions/), [Atlantis](https://atmos.tools/integrations/atlantis), or [Spacelift](https://atmos.tools/integrations/spacelift). > @@ -39,11 +33,7 @@ Terraform module to provision a CloudFlare zone with: DNS records, Argo, Firewal > Watch demo of using Atmos with Terraform >
> Example of running atmos to manage infrastructure from our Quick Start tutorial. -> - - - - +> ## Usage @@ -95,20 +85,14 @@ module "zone" { > you're using. This practice ensures the stability of your infrastructure. Additionally, we recommend implementing a systematic > approach for updating versions to avoid unexpected changes. - - - - ## Examples Here is an example of using this module: -- [`examples/complete`](examples/complete) - complete example of using this module - - +- [`examples/complete`](examples/complete) - complete example of using this module - ## Makefile Targets + ```text Available targets: @@ -118,22 +102,21 @@ Available targets: lint Lint terraform code ``` - - + ## Requirements | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0.0 | -| [cloudflare](#requirement\_cloudflare) | >= 3.23 | +| [cloudflare](#requirement\_cloudflare) | >= 4.0 | | [time](#requirement\_time) | >= 0.8 | ## Providers | Name | Version | |------|---------| -| [cloudflare](#provider\_cloudflare) | >= 3.23 | -| [time](#provider\_time) | >= 0.8 | +| [cloudflare](#provider\_cloudflare) | 4.34.0 | +| [time](#provider\_time) | 0.11.2 | ## Modules @@ -146,8 +129,6 @@ Available targets: | Name | Type | |------|------| | [cloudflare_argo.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/argo) | resource | -| [cloudflare_filter.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/filter) | resource | -| [cloudflare_firewall_rule.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/firewall_rule) | resource | | [cloudflare_healthcheck.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/healthcheck) | resource | | [cloudflare_page_rule.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/page_rule) | resource | | [cloudflare_record.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource | @@ -170,7 +151,6 @@ Available targets: | [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| [firewall\_rules](#input\_firewall\_rules) | paused:
Whether this filter is currently paused.
expression:
The filter expression to be used.
description:
A note that you can use to describe the purpose of the filter and rule.
ref:
Short reference tag to quickly select related rules.
action:
The action to apply to a matched request.
Possible values: `block`, `challenge`, `allow`, `js_challenge`, `bypass`.
priority:
The priority of the rule to allow control of processing order.
A lower number indicates high priority.
If not provided, any rules with a priority will be sequenced before those without.
products:
List of products to bypass for a request when the bypass action is used.
Possible values: `zoneLockdown`, `uaBlock`, `bic`, `hot`, `securityLevel`, `rateLimit`, `waf`. | `list(any)` | `null` | no | | [healthchecks](#input\_healthchecks) | A list of maps of Health Checks rules.
The values of map is fully compliant with `cloudflare_healthcheck` resource.
To get more info see https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/healthcheck | `list(any)` | `null` | no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | | [jump\_start](#input\_jump\_start) | Whether to scan for DNS records on creation. | `bool` | `false` | no | @@ -196,8 +176,6 @@ Available targets: | Name | Description | |------|-------------| -| [filter\_ids](#output\_filter\_ids) | A list of filter IDs. | -| [firewall\_rule\_ids](#output\_firewall\_rule\_ids) | A list of firewall rule IDs. | | [id](#output\_id) | The zone ID. | | [meta\_phishing\_detected](#output\_meta\_phishing\_detected) | Indicates if URLs on the zone have been identified as hosting phishing content. | | [meta\_wildcard\_proxiable](#output\_meta\_wildcard\_proxiable) | Indicates whether wildcard DNS records can receive Cloudflare security and performance features. | @@ -210,7 +188,6 @@ Available targets: | [verification\_key](#output\_verification\_key) | Contains the TXT record value to validate domain ownership. This is only populated for zones of type `partial`. | - ## Related Projects Check out these related projects. @@ -218,17 +195,15 @@ Check out these related projects. - [terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Terraform Module to define a consistent naming convention by (namespace, stage, name, [attributes]) - [terraform-cloudflare-waf-rulesets](https://github.com/cloudposse/terraform-cloudflare-waf-rulesets) - Terraform module to manage CloudFlare WAF rulesetes - ## References For additional context, refer to some of these links. - [terraform-provider-cloudflare](https://registry.terraform.io/providers/cloudflare/cloudflare/latest) - Cloudflare Terraform Provider - - > [!TIP] -> #### Use Terraform Reference Architectures for AWS +> +> ### Use Terraform Reference Architectures for AWS > > Use Cloud Posse's ready-to-go [terraform architecture blueprints](https://cloudposse.com/reference-architecture/) for AWS to get up and running quickly. > @@ -246,7 +221,9 @@ For additional context, refer to some of these links. > *Your team can operate like a pro today.* > > Ensure that your team succeeds by using Cloud Posse's proven process and turnkey blueprints. Plus, we stick around until you succeed. -> #### Day-0: Your Foundation for Success +> +> ### Day-0: Your Foundation for Success +> > - **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code. > - **Deployment Strategy.** Adopt a proven deployment strategy with GitHub Actions, enabling automated, repeatable, and reliable software releases. > - **Site Reliability Engineering.** Gain total visibility into your applications and services with Datadog, ensuring high availability and performance. @@ -255,7 +232,8 @@ For additional context, refer to some of these links. > > Request Quote > -> #### Day-2: Your Operational Mastery +> ### Day-2: Your Operational Mastery +> > - **Training.** Equip your team with the knowledge and skills to confidently manage the infrastructure, ensuring long-term success and self-sufficiency. > - **Support.** Benefit from a seamless communication over Slack with our experts, ensuring you have the support you need, whenever you need it. > - **Troubleshooting.** Access expert assistance to quickly resolve any operational challenges, minimizing downtime and maintaining business continuity. @@ -271,8 +249,6 @@ For additional context, refer to some of these links. This project is under active development, and we encourage contributions from our community. - - Many thanks to our outstanding contributors: @@ -282,6 +258,7 @@ Many thanks to our outstanding contributors: For 🐛 bug reports & feature requests, please use the [issue tracker](https://github.com/cloudposse/terraform-cloudflare-zone/issues). In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. + 1. Review our [Code of Conduct](https://github.com/cloudposse/terraform-cloudflare-zone/?tab=coc-ov-file#code-of-conduct) and [Contributor Guidelines](https://github.com/cloudposse/.github/blob/main/CONTRIBUTING.md). 2. **Fork** the repo on GitHub 3. **Clone** the project to your own machine @@ -333,19 +310,17 @@ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` + ## Trademarks All other trademarks referenced herein are the property of their respective owners. - ## Copyrights Copyright © 2021-2024 [Cloud Posse, LLC](https://cloudposse.com) - - README footer Beacon diff --git a/docs/terraform.md b/docs/terraform.md index 8ca4262..f063a29 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -4,15 +4,15 @@ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0.0 | -| [cloudflare](#requirement\_cloudflare) | >= 3.23 | +| [cloudflare](#requirement\_cloudflare) | >= 4.0 | | [time](#requirement\_time) | >= 0.8 | ## Providers | Name | Version | |------|---------| -| [cloudflare](#provider\_cloudflare) | >= 3.23 | -| [time](#provider\_time) | >= 0.8 | +| [cloudflare](#provider\_cloudflare) | 4.34.0 | +| [time](#provider\_time) | 0.11.2 | ## Modules @@ -25,8 +25,6 @@ | Name | Type | |------|------| | [cloudflare_argo.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/argo) | resource | -| [cloudflare_filter.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/filter) | resource | -| [cloudflare_firewall_rule.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/firewall_rule) | resource | | [cloudflare_healthcheck.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/healthcheck) | resource | | [cloudflare_page_rule.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/page_rule) | resource | | [cloudflare_record.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource | @@ -49,7 +47,6 @@ | [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| [firewall\_rules](#input\_firewall\_rules) | paused:
Whether this filter is currently paused.
expression:
The filter expression to be used.
description:
A note that you can use to describe the purpose of the filter and rule.
ref:
Short reference tag to quickly select related rules.
action:
The action to apply to a matched request.
Possible values: `block`, `challenge`, `allow`, `js_challenge`, `bypass`.
priority:
The priority of the rule to allow control of processing order.
A lower number indicates high priority.
If not provided, any rules with a priority will be sequenced before those without.
products:
List of products to bypass for a request when the bypass action is used.
Possible values: `zoneLockdown`, `uaBlock`, `bic`, `hot`, `securityLevel`, `rateLimit`, `waf`. | `list(any)` | `null` | no | | [healthchecks](#input\_healthchecks) | A list of maps of Health Checks rules.
The values of map is fully compliant with `cloudflare_healthcheck` resource.
To get more info see https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/healthcheck | `list(any)` | `null` | no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | | [jump\_start](#input\_jump\_start) | Whether to scan for DNS records on creation. | `bool` | `false` | no | @@ -75,8 +72,6 @@ | Name | Description | |------|-------------| -| [filter\_ids](#output\_filter\_ids) | A list of filter IDs. | -| [firewall\_rule\_ids](#output\_firewall\_rule\_ids) | A list of firewall rule IDs. | | [id](#output\_id) | The zone ID. | | [meta\_phishing\_detected](#output\_meta\_phishing\_detected) | Indicates if URLs on the zone have been identified as hosting phishing content. | | [meta\_wildcard\_proxiable](#output\_meta\_wildcard\_proxiable) | Indicates whether wildcard DNS records can receive Cloudflare security and performance features. | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index ca00aec..f6fcc0d 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -35,14 +35,6 @@ module "zone" { } ] - firewall_rules = [ - { - expression = "(ip.src eq 192.168.0.1)" - description = "Block access from 192.168.0.1" - action = "block" - } - ] - healthchecks = [ { address = format("bastion-%s.%s", join("", var.attributes), var.zone) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index ad103d1..64d1cdf 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -8,16 +8,6 @@ output "zone_record_hostnames_to_ids" { value = module.zone.record_hostnames_to_ids } -output "zone_filter_ids" { - description = "A list of filter IDs." - value = module.zone.filter_ids -} - -output "zone_firewall_rule_ids" { - description = "A list of firewall rule IDs." - value = module.zone.firewall_rule_ids -} - output "zone_page_rule_targets_to_ids" { description = "A map of the page rule targets to IDs." value = module.zone.page_rule_targets_to_ids diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index 3032e8a..c4c482a 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" - version = ">= 3.23" + version = ">= 4.0" } time = { source = "hashicorp/time" diff --git a/firewall.tf b/firewall.tf deleted file mode 100644 index b63f897..0000000 --- a/firewall.tf +++ /dev/null @@ -1,31 +0,0 @@ -locals { - firewall_rules = module.this.enabled && var.firewall_rules != null ? { - for rule in flatten(var.firewall_rules) : - format("%s-%s", - rule.action, - md5(rule.expression), - ) => rule - } : {} -} - -resource "cloudflare_filter" "default" { - for_each = local.firewall_rules - - zone_id = local.zone_id - description = each.value.description - expression = each.value.expression - paused = lookup(each.value, "paused", null) - ref = lookup(each.value, "ref", null) -} - -resource "cloudflare_firewall_rule" "default" { - for_each = local.firewall_rules - - zone_id = local.zone_id - description = each.value.description - action = each.value.action - priority = lookup(each.value, "priority", null) - paused = lookup(each.value, "paused", null) - products = lookup(each.value, "products", null) - filter_id = cloudflare_filter.default[each.key].id -} diff --git a/main.tf b/main.tf index 03478e8..2a31d49 100644 --- a/main.tf +++ b/main.tf @@ -1,7 +1,7 @@ locals { - tiered_caching = local.argo_enabed && var.argo_tiered_caching_enabled ? "on" : "off" - smart_routing = local.argo_enabed && var.argo_smart_routing_enabled ? "on" : "off" - argo_enabed = module.this.enabled && var.argo_enabled + tiered_caching = local.argo_enabled && var.argo_tiered_caching_enabled ? "on" : "off" + smart_routing = local.argo_enabled && var.argo_smart_routing_enabled ? "on" : "off" + argo_enabled = module.this.enabled && var.argo_enabled zone_enabled = module.this.enabled && var.zone_enabled zone_exists = module.this.enabled && !var.zone_enabled records_enabled = module.this.enabled && length(var.records) > 0 @@ -44,7 +44,7 @@ resource "cloudflare_record" "default" { } resource "cloudflare_argo" "default" { - count = local.argo_enabed ? 1 : 0 + count = local.argo_enabled ? 1 : 0 zone_id = local.zone_id tiered_caching = local.tiered_caching diff --git a/outputs.tf b/outputs.tf index e706cc8..94ae866 100644 --- a/outputs.tf +++ b/outputs.tf @@ -12,16 +12,6 @@ output "record_hostnames_to_ids" { } } -output "filter_ids" { - description = "A list of filter IDs." - value = try(values(cloudflare_filter.default)[*]["id"], null) -} - -output "firewall_rule_ids" { - description = "A list of firewall rule IDs." - value = try(values(cloudflare_firewall_rule.default)[*]["id"], null) -} - output "plan" { description = "The name of the commercial plan to apply to the zone." value = join("", cloudflare_zone.default[*].plan) diff --git a/variables.tf b/variables.tf index d535080..739ee3e 100644 --- a/variables.tf +++ b/variables.tf @@ -97,31 +97,6 @@ variable "healthchecks" { DOC } -variable "firewall_rules" { - type = list(any) - default = null - description = <<-DOC - paused: - Whether this filter is currently paused. - expression: - The filter expression to be used. - description: - A note that you can use to describe the purpose of the filter and rule. - ref: - Short reference tag to quickly select related rules. - action: - The action to apply to a matched request. - Possible values: `block`, `challenge`, `allow`, `js_challenge`, `bypass`. - priority: - The priority of the rule to allow control of processing order. - A lower number indicates high priority. - If not provided, any rules with a priority will be sequenced before those without. - products: - List of products to bypass for a request when the bypass action is used. - Possible values: `zoneLockdown`, `uaBlock`, `bic`, `hot`, `securityLevel`, `rateLimit`, `waf`. - DOC -} - variable "page_rules" { type = list(any) default = null diff --git a/versions.tf b/versions.tf index 3032e8a..c4c482a 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" - version = ">= 3.23" + version = ">= 4.0" } time = { source = "hashicorp/time"