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

feat: initial implementation #1

Merged
merged 4 commits into from
Mar 30, 2021
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
206 changes: 127 additions & 79 deletions README.md

Large diffs are not rendered by default.

115 changes: 69 additions & 46 deletions README.yaml
Original file line number Diff line number Diff line change
@@ -1,64 +1,52 @@
---
#
# This is the canonical configuration for the `README.md`
# Run `make readme` to rebuild the `README.md`
#

# Name of this project
name: terraform-example-module
name: terraform-cloudflare-waf-rulesets

# Logo for this project
#logo: docs/logo.png

# License of this project
license: "APACHE2"
license: APACHE2

# Copyrights
copyrights:
- name: "Cloud Posse, LLC"
url: "https://cloudposse.com"
year: "2020"
- name: Cloud Posse, LLC
url: https://cloudposse.com
year: '2021'

# Canonical GitHub repo
github_repo: cloudposse/terraform-example-module
github_repo: cloudposse/terraform-cloudflare-waf-rulesets

# Badges to display
badges:
- name: "Latest Release"
image: "https://img.shields.io/github/release/cloudposse/terraform-example-module.svg"
url: "https://github.com/cloudposse/terraform-example-module/releases/latest"
- name: "Slack Community"
image: "https://slack.cloudposse.com/badge.svg"
url: "https://slack.cloudposse.com"
- name: "Discourse Forum"
image: "https://img.shields.io/discourse/https/ask.sweetops.com/posts.svg"
url: "https://ask.sweetops.com/"
- name: Latest Release
image: https://img.shields.io/github/release/cloudposse/terraform-cloudflare-waf-rulesets.svg
url: https://github.com/cloudposse/terraform-cloudflare-waf-rulesets/releases/latest
- name: Slack Community
image: https://slack.cloudposse.com/badge.svg
url: https://slack.cloudposse.com

# List any related terraform modules that this module may be used with or that this module depends on.
related:
- name: "terraform-null-label"
description: "Terraform module designed to generate consistent names and tags for resources. Use terraform-null-label to implement a strict naming convention."
url: "https://github.com/cloudposse/terraform-null-label"

# List any resources helpful for someone to get started. For example, link to the hashicorp documentation or AWS documentation.
- name: terraform-null-label
description: Terraform Module to define a consistent naming convention by (namespace,
stage, name, [attributes])
url: https://github.com/cloudposse/terraform-null-label
- name: terraform-cloudflare-zone
description:
url: https://github.com/cloudposse/terraform-cloudflare-zone
references:
- name: "Terraform Standard Module Structure"
description: "HashiCorp's standard module structure is a file and directory layout we recommend for reusable modules distributed in separate repositories."
url: "https://www.terraform.io/docs/modules/index.html#standard-module-structure"
- name: "Terraform Module Requirements"
description: "HashiCorp's guidance on all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy."
url: "https://www.terraform.io/docs/registry/modules/publish.html#requirements"
- name: "Terraform `random_integer` Resource"
description: "The resource random_integer generates random values from a given range, described by the min and max attributes of a given resource."
url: "https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer"
- name: "Terraform Version Pinning"
description: "The required_version setting can be used to constrain which versions of the Terraform CLI can be used with your configuration"
url: "https://www.terraform.io/docs/configuration/terraform.html#specifying-a-required-terraform-version"

# Short description of this project
- name: terraform-provider-cloudflare
description: Cloudflare Terraform Provider
url: https://registry.terraform.io/providers/cloudflare/cloudflare/latest
description: |-
This is `terraform-example-module` project provides all the scaffolding for a typical well-built Cloud Posse module. It's a template repository you can
use when creating new repositories.
Terraform module to manage CloudFlare WAF rulesetes.

__NOTE:__ This module is a hard fork of [Innovation Norway's](https://github.com/innovationnorway/terraform-cloudflare-waf-rulesets) terraform module and adapted to Cloud Posse conventions.

# Introduction to the project
#introduction: |-
Expand All @@ -67,32 +55,67 @@ description: |-
# How to use this module. Should be an easy example to copy and paste.
usage: |-
For a complete example, see [examples/complete](examples/complete).

For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest)
(which tests and deploys the example on AWS), see [test](test).

```hcl
module "example" {
source = "https://github.com/cloudposse/terraform-example-module.git?ref=master"
example = "Hello world!"
module "label" {
source = "cloudposse/label/null"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
namespace = "eg"
stage = "prod"
name = "waf"
attributes = ["cf"]
delimiter = "-"
}

module "waf_rulesets" {
source = "cloudposse/waf-rulesets/cloudflare"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
zone = "cloudposse.co"

rulesets = [
{
name = "OWASP ModSecurity Core Rule Set"
mode = "simulate"
sensitivity = "off"
rule_groups = [
{
name = "OWASP Bad Robots"
mode = "on"
rules = [
{
id = "990012" # Rogue web site crawler
mode = "off"
},
]
},
]
},
]

context = module.label.context
}
```

# Example usage
examples: |-
Here is an example of using this module:
- [`examples/complete`](https://github.com/cloudposse/terraform-example-module/) - complete example of using this module
- [`examples/complete`](examples/complete) - complete example of using this module

# How to get started quickly
#quickstart: |-
# Here's how to get started...

# Other files to include in this README from the project folder
include:
- "docs/targets.md"
- "docs/terraform.md"
- docs/targets.md
- docs/terraform.md

# Contributors to this project
contributors:
- name: "Erik Osterman"
github: "osterman"
- name: Vladimir Syromyatnikov
github: SweetOps
62 changes: 38 additions & 24 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,57 @@

| Name | Version |
|------|---------|
| terraform | >= 0.13 |
| local | >= 1.2 |
| random | >= 2.2 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13 |
| <a name="requirement_cloudflare"></a> [cloudflare](#requirement\_cloudflare) | >= 2.19 |

## Providers

| Name | Version |
|------|---------|
| random | >= 2.2 |
| <a name="provider_cloudflare"></a> [cloudflare](#provider\_cloudflare) | >= 2.19 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.24.1 |

## Resources

| Name | Type |
|------|------|
| [cloudflare_waf_group.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/waf_group) | resource |
| [cloudflare_waf_package.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/waf_package) | resource |
| [cloudflare_waf_rule.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/waf_rule) | resource |
| [cloudflare_waf_groups.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/waf_groups) | data source |
| [cloudflare_waf_packages.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/waf_packages) | data source |
| [cloudflare_zones.default](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zones) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
| attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
| context | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_key_case": null,<br> "label_order": [],<br> "label_value_case": null,<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {}<br>}</pre> | no |
| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| enabled | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| environment | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| example | Example variable | `string` | `"hello world"` | no |
| id\_length\_limit | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for default, which is `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| label\_key\_case | The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`.<br>Possible values: `lower`, `title`, `upper`.<br>Default value: `title`. | `string` | `null` | no |
| label\_order | The naming order of the id output and Name tag.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no |
| label\_value\_case | The letter case of output label values (also used in `tags` and `id`).<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Default value: `lower`. | `string` | `null` | no |
| name | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no |
| namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no |
| regex\_replace\_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |
| <a name="input_additional_tag_map"></a> [additional\_tag\_map](#input\_additional\_tag\_map) | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
| <a name="input_context"></a> [context](#input\_context) | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_key_case": null,<br> "label_order": [],<br> "label_value_case": null,<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {}<br>}</pre> | no |
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for default, which is `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| <a name="input_label_key_case"></a> [label\_key\_case](#input\_label\_key\_case) | The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`.<br>Possible values: `lower`, `title`, `upper`.<br>Default value: `title`. | `string` | `null` | no |
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The naming order of the id output and Name tag.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | The letter case of output label values (also used in `tags` and `id`).<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Default value: `lower`. | `string` | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no |
| <a name="input_namespace"></a> [namespace](#input\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_rulesets"></a> [rulesets](#input\_rulesets) | A list of `rulesets` objects.<br>name:<br> The name of the firewall package.<br>sensitivity:<br> The sensitivity of the firewall package.<br>mode:<br> The default action that will be taken for rules under the firewall package. <br> Possible values: `simulate`, `block`, `challenge`.<br>rule\_groups:<br> name:<br> The name of the firewall rule group.<br> mode:<br> Whether or not the rules contained within this group are configurable/usable. <br> Possible values: `on`, `off`.<br>rules:<br> id:<br> The ID of the WAF rule.<br> mode:<br> The mode to use when the rule is triggered. Value is restricted based on the allowed\_modes of the rule. <br> Possible values: `default`, `disable`, `simulate`, `block`, `challenge`, `on`, `off`. | <pre>list(object({<br> name = string<br> sensitivity = string<br> mode = string<br> rule_groups = list(object({<br> name = string<br> mode = string<br> rules = list(object({<br> id = string<br> mode = string<br> }))<br> }))<br> }))</pre> | n/a | yes |
| <a name="input_stage"></a> [stage](#input\_stage) | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |
| <a name="input_zone"></a> [zone](#input\_zone) | The name of the DNS zone. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| example | Example output |
| id | ID of the created example |
| random | Stable random number for this example |

| <a name="output_rulesets"></a> [rulesets](#output\_rulesets) | A list of `rulesets` objects. |
<!-- markdownlint-restore -->
2 changes: 1 addition & 1 deletion examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
region = "us-east-2"
zone = "test-automation.app"

namespace = "eg"

Expand Down
24 changes: 22 additions & 2 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
module "example" {
module "waf_rulesets" {
source = "../.."

example = var.example
zone = var.zone

rulesets = [
{
name = "OWASP ModSecurity Core Rule Set"
mode = "simulate"
sensitivity = "off"
rule_groups = [
{
name = "OWASP Bad Robots"
mode = "on"
rules = [
{
id = "990012" # Rogue web site crawler
mode = "off"
},
]
},
]
},
]

context = module.this.context
}
16 changes: 3 additions & 13 deletions examples/complete/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
output "id" {
description = "ID of the created example"
value = module.example.id
}

output "example" {
description = "Output \"example\" from example module"
value = module.example.example
}

output "random" {
description = "Output \"random\" from example module"
value = module.example.random
output "rulesets" {
description = "A list of `rulesets` objects."
value = module.waf_rulesets.rulesets
}
4 changes: 2 additions & 2 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
variable "example" {
variable "zone" {
type = string
description = "The value which will be passed to the example module"
description = "The name of the DNS zone."
}
8 changes: 4 additions & 4 deletions examples/complete/versions.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
terraform {
required_version = ">= 0.12.26"
required_version = ">= 0.13"

required_providers {
local = {
source = "hashicorp/local"
version = ">= 1.2"
cloudflare = {
source = "cloudflare/cloudflare"
version = ">= 2.19"
}
}
}
Loading