14 Commits
v0.0.2 ... main

Author SHA1 Message Date
c6e7f312e6 Merge pull request #8 from jimeh/release-please--branches--main 2026-02-02 16:59:13 +00:00
jimehbot[bot]
8094a369d4 chore(main): release 0.0.3 2026-02-02 15:38:11 +00:00
be748ca04f Merge pull request #7 from jimeh/add-ci-job 2026-02-02 15:37:52 +00:00
1ca228673e ci: add CI workflow with fmt, validate, docs, lint, and release-please jobs
Replace the standalone release-please workflow with a unified CI
workflow that runs formatting checks, terraform validate, docs
freshness, and tflint on every push. Release-please is now handled
by jimeh/release-please-manifest-action with GitHub App auth.

Also:
- Move release-please config files under .github/
- Add changelog-sections and always-update to release-please config
- Add tflint with recommended terraform plugin preset
- Add .gitignore for .terraform/ and .terraform.lock.hcl
- Add lint and lint-fix Make targets
- Clean .terraform.lock.hcl before terraform-docs runs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:20:15 +00:00
6da178a5d0 fix: specify minimum required terraform version (>= 1.1)
The module uses `nullable = false` on variables which requires
Terraform 1.1+. Without `required_version` set, users on older
versions would get confusing errors instead of a clear version
constraint message.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 15:19:36 +00:00
3203c27686 Merge pull request #6 from jimeh/chore/docs-generation-and-formatting-automation 2026-02-02 14:35:09 +00:00
8bdc77a2c9 chore: automate README docs generation and formatting
Manual `terraform-docs markdown .` was fragile — no injection markers,
no idempotency check, and no consistent formatting pipeline.

Add terraform-docs inject mode with BEGIN/END_TF_DOCS markers in the
README so `terraform-docs .` regenerates only the managed section.
Wrap the injected block with prettier-ignore directives to prevent
prettier from reformatting tables (which would break terraform-docs
--output-check).

Restructure Makefile with three targets:
- `docs`: regenerate terraform-docs + prettier format README
- `fmt`: docs + terraform fmt -recursive
- `check`: verify all docs/formatting are current (CI-friendly)

Add node (LTS) and prettier to .mise.toml for markdown formatting.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:32:57 +00:00
1c2115b725 Merge pull request #5 from jimeh/docs/fix-truncated-sentence-in-readme 2026-02-02 14:19:20 +00:00
0de0ea55dd docs(readme): fix truncated sentence in Google Workspace example
The sentence about MX records was cut off mid-thought, leaving readers
without the actionable advice to use the records given by Google.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:18:55 +00:00
36e97775f0 Merge pull request #4 from jimeh/chore/add-claude-code-config 2026-02-02 14:14:45 +00:00
bd2e0128df chore: add Claude Code configuration files
Provide project context and coding guidelines for Claude Code via
AGENTS.md (architecture, conventions, commands) and CLAUDE.md (pointer
to AGENTS.md).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:12:11 +00:00
2e5fcffed3 Merge pull request #3 from jimeh/chore/add-mise-config-and-update-docs 2026-02-02 14:11:00 +00:00
52c89c91d2 chore: add mise config and regenerate terraform-docs
Add .mise.toml to pin terraform and terraform-docs tool versions.
Regenerate README.md via terraform-docs, which reformats the
input/output/requirement tables and escapes underscores in markdown
links.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 14:10:32 +00:00
1931ed281d docs(readme): expand Example Usage section with more details and examples 2023-04-26 02:48:41 +01:00
16 changed files with 417 additions and 87 deletions

3
.github/.release-please-manifest.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
".": "0.0.3"
}

31
.github/release-please-config.json vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"packages": {
".": {
"release-type": "simple",
"changelog-path": "CHANGELOG.md",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"draft": false,
"prerelease": false,
"always-update": true,
"include-component-in-tag": false,
"extra-files": [
"README.md"
],
"changelog-sections": [
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "perf", "section": "Performance Improvements" },
{ "type": "revert", "section": "Reverts" },
{ "type": "docs", "section": "Documentation" },
{ "type": "style", "section": "Styles", "hidden": true },
{ "type": "chore", "section": "Miscellaneous", "hidden": true },
{ "type": "refactor", "section": "Code Refactoring", "hidden": true },
{ "type": "test", "section": "Tests", "hidden": true },
{ "type": "build", "section": "Build System", "hidden": true },
{ "type": "ci", "section": "CI", "hidden": true }
]
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

49
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
---
name: CI
on: [push]
permissions:
contents: read
jobs:
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
- run: terraform fmt -check -recursive -diff
- run: prettier --check README.md
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
- run: terraform init -backend=false
- run: terraform validate
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
- run: terraform-docs --output-check .
- run: prettier --check README.md
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
- run: tflint --init
- run: tflint --format compact
release-please:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/heads/')
steps:
- uses: jimeh/release-please-manifest-action@84f33fd2828210488c36f3e0a7e3209252d2ae7d # v3.0.0
with:
target-branch-pattern: "^(main|master)$"
app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}

View File

@@ -1,16 +0,0 @@
---
on: push
jobs:
release-please:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
outputs:
release_created: ${{ steps.release-please.outputs.release_created }}
tag_name: ${{ steps.release-please.outputs.tag_name }} # e.g. v1.0.0
version: ${{ steps.release-please.outputs.version }} # e.g. 1.0.0
steps:
- uses: google-github-actions/release-please-action@v3
id: release-please
with:
command: manifest

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.terraform/
.terraform.lock.hcl

6
.mise.toml Normal file
View File

@@ -0,0 +1,6 @@
[tools]
"npm:prettier" = "latest"
node = "lts"
terraform = "latest"
terraform-docs = "latest"
tflint = "latest"

View File

@@ -1,3 +0,0 @@
{
".": "0.0.2"
}

8
.terraform-docs.yml Normal file
View File

@@ -0,0 +1,8 @@
formatter: "markdown table"
output:
file: "README.md"
mode: inject
settings:
hide-empty: false
read-comments: true

4
.tflint.hcl Normal file
View File

@@ -0,0 +1,4 @@
plugin "terraform" {
enabled = true
preset = "recommended"
}

49
AGENTS.md Normal file
View File

@@ -0,0 +1,49 @@
# AGENTS.md
Terraform module for configuring email-related DNS records and services on
Cloudflare. Manages MX, SPF, DMARC, DKIM, TLSRPT, and MTA-STS — including a
Cloudflare Worker + KV to serve the MTA-STS policy file.
## Commands
- `make docs` — regenerate README input/output tables via `terraform-docs`
- `terraform fmt` — format HCL files
- `terraform validate` — validate configuration
Tool versions managed with [mise](https://mise.jdx.dev/) (see `.mise.toml`).
## Architecture
Single flat module — all resources in `main.tf`, organized by section comments:
- **General** — `cloudflare_zone` data source lookup
- **MX** — MX records for root domain + optional subdomains, flattened via
`locals` into a `for_each` map
- **SPF** — single TXT record built from configurable terms list
- **TLS SMTP** — TLSRPT TXT record
- **MTA-STS** — the most involved piece:
- Proxied A/AAAA records for `mta-sts.` subdomain (dummy IPs, Cloudflare
proxies the traffic)
- `_mta-sts` TXT record with SHA1-based policy version
- Workers KV namespace + KV entry holding the rendered policy
(`mta-sts.txt.tpl`)
- Worker script (`mta-sts.js`) serving the policy from KV
- Worker route binding `mta-sts.<domain>/*`
- **DMARC** — TXT record assembled from multiple variables with mode
abbreviation lookup (`relaxed``r`, `strict``s`)
- **Domain Keys (DKIM)** — `for_each` over a map of DKIM keys, supports both
TXT and CNAME record types
## Conventions
- All DNS resources use `for_each` (not `count`).
- Extensive variable validation blocks with custom error messages.
- Section comments (`# MX`, `# SPF`, etc.) separate logical groups in all
`.tf` files.
- Provider constraint: `cloudflare/cloudflare >= 3.0, < 5.0`.
## Releases
Automated via [release-please](https://github.com/googleapis/release-please).
Uses conventional commits — pushes to `main` trigger the release-please GitHub
Action which manages changelog, version bumps, and GitHub releases.

View File

@@ -1,5 +1,18 @@
# Changelog
## [0.0.3](https://github.com/jimeh/terraform-cloudflare-email/compare/v0.0.2...v0.0.3) (2026-02-02)
### Bug Fixes
* specify minimum required terraform version (&gt;= 1.1) ([6da178a](https://github.com/jimeh/terraform-cloudflare-email/commit/6da178a5d0adbe1500357dd1a4987faa8e3b85ff))
### Documentation
* **readme:** expand Example Usage section with more details and examples ([1931ed2](https://github.com/jimeh/terraform-cloudflare-email/commit/1931ed281d0c3c71d1a056e21388aeb2415de63a))
* **readme:** fix truncated sentence in Google Workspace example ([0de0ea5](https://github.com/jimeh/terraform-cloudflare-email/commit/0de0ea55ddb1cd95f3f4edef30f7f2d973baa4b0))
## [0.0.2](https://github.com/jimeh/terraform-cloudflare-email/compare/v0.0.1...v0.0.2) (2023-04-26)

1
CLAUDE.md Normal file
View File

@@ -0,0 +1 @@
@AGENTS.md

View File

@@ -1,4 +1,23 @@
.PHONY: docs
.SILENT: docs
.PHONY: docs fmt lint lint-fix check
docs:
terraform-docs markdown .
rm -f .terraform.lock.hcl
terraform-docs .
prettier --write README.md
fmt: docs
terraform fmt -recursive
lint:
tflint --init
tflint --format compact
lint-fix:
tflint --init
tflint --fix
check: lint
rm -f .terraform.lock.hcl
terraform-docs --output-check .
prettier --check README.md
terraform fmt -check -recursive

276
README.md
View File

@@ -42,13 +42,32 @@ including serving a MTA-STS policy text file via Cloudflare Workers.
<!-- x-release-please-start-version -->
Examples assume that you have the following variables setup:
- `cloudflare_account_id` — Your Account ID.
- `cloudflare_zone_id` — ID of the Zone (domain name).
- `cloudflare_zone_name` — Domain name, e.g. `foobar.com`.
Adjust examples as needed to fit your setup.
### Google Workspace
Below example is based on the
[DNS Basics](https://support.google.com/a/answer/48090?hl=en) support article.
When going through the domain setup wizard within the Google Workspace Admin,
you are likely to be given a slightly different list of MX records, and
obviously you should use the ones that are given to you by Google.
Also make sure you generate your own domain key from under Apps > Google
Workspace > Gmail > Authenticate Email.
<details>
<summary>Gmail</summary>
<summary><code>main.tf</code></summary>
```terraform
module "email" {
source = "jimeh/email/cloudflare"
version = "0.0.2"
version = "0.0.3"
account_id = var.cloudflare_account_id
zone_id = var.cloudflare_zone_id
@@ -57,8 +76,8 @@ module "email" {
"aspmx.l.google.com" = 1
"alt1.aspmx.l.google.com" = 5
"alt2.aspmx.l.google.com" = 5
"alt3.aspmx.l.google.com" = 10
"alt4.aspmx.l.google.com" = 10
"aspmx2.googlemail.com" = 10
"aspmx3.googlemail.com" = 10
}
spf_terms = [
@@ -73,6 +92,7 @@ module "email" {
"*.googlemail.com",
"aspmx.l.google.com",
]
tlsrpt_rua = [
"mailto:tls-report@${var.cloudflare_zone_name}",
]
@@ -86,6 +106,7 @@ module "email" {
"google" = {
type = "TXT"
value = join("", [
# TODO: Replace this example key with a real one.
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApAVNwJ9",
"+6ArXN23ZaR8SFSYxVEEbbHRZplZqHVt6uEpcirY+jxHOqV2bvqAY3BHZQs/KoHnFSWUf",
"6zv6ajZgUxvU65UhCbrQ7CwrJCjU8sQFDk+CpbvmXyJIe9G470HuGEs4NmQDoddJZr09V",
@@ -96,23 +117,178 @@ module "email" {
}
}
}
resource "cloudflare_record" "cname" {
for_each = {
"mail" = { value = "ghs.googlehosted.com", proxied = false }
}
name = lookup(each.value, "name", each.key)
proxied = lookup(each.value, "proxied", false)
ttl = lookup(each.value, "ttl", 1)
type = "CNAME"
value = each.value.value
zone_id = var.cloudflare_zone_id
}
resource "cloudflare_record" "txt" {
for_each = {
"google" = {
value = (
"google-site-verification=__REPLACE_ME_WITH_A_REAL_VALUE__"
)
}
}
name = lookup(each.value, "name", local.zone_name)
proxied = lookup(each.value, "proxied", false)
ttl = lookup(each.value, "ttl", 1)
type = "TXT"
value = each.value.value
zone_id = var.cloudflare_zone_id
}
```
</details>
### Fastmail
The below example is based on Fastmail's
[Manual DNS configuration](https://www.fastmail.help/hc/en-us/articles/360060591153-Manual-DNS-configuration)
help article.
<details>
<summary><code>main.tf</code></summary>
```terraform
module "email" {
source = "jimeh/email/cloudflare"
version = "0.0.3"
account_id = var.cloudflare_account_id
zone_id = var.cloudflare_zone_id
mx = {
"in1-smtp.messagingengine.com" = 10
"in2-smtp.messagingengine.com" = 20
}
mx_subdomains = ["*"]
spf_terms = [
"include:spf.messagingengine.com",
"?all"
]
mta_sts_mode = "enforce"
mta_sts_max_age = 86400
mta_sts_mx = [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
]
tlsrpt_rua = [
"mailto:tls-report@${var.cloudflare_zone_name}",
]
dmarc_policy = "reject"
dmarc_rua = [
"mailto:dmarc-report@${var.cloudflare_zone_name}",
]
domainkeys = {
"fm1" = {
type = "CNAME"
value = "fm1.${var.cloudflare_zone_name}.dkim.fmhosted.com"
}
"fm2" = {
type = "CNAME"
value = "fm2.${var.cloudflare_zone_name}.dkim.fmhosted.com"
}
"fm3" = {
type = "CNAME"
value = "fm3.${var.cloudflare_zone_name}.dkim.fmhosted.com"
}
"mesmtp" = {
type = "CNAME"
value = "mesmtp.${var.cloudflare_zone_name}.dkim.fmhosted.com"
}
}
}
resource "cloudflare_record" "srv" {
for_each = {
"_caldav._tcp" = {}
"_caldavs._tcp" = {
port = 433
target = "caldav.fastmail.com"
weight = 1
}
"_carddav._tcp" = {}
"_carddavs._tcp" = {
port = 443
target = "carddav.fastmail.com"
weight = 1
}
"_imap._tcp" = {}
"_imaps._tcp" = {
port = 993
target = "imap.fastmail.com"
weight = 1
}
"_jmap._tcp" = {
port = 443
target = "jmap.fastmail.com"
weight = 1
}
"_pop3._tcp" = {}
"_pop3s._tcp" = {
port = 995
priority = 10
target = "pop.fastmail.com"
weight = 1
}
"_submission._tcp" = {
port = 587
target = "smtp.fastmail.com"
weight = 1
}
}
name = lookup(each.value, "name", each.key)
proxied = lookup(each.value, "proxied", false)
ttl = lookup(each.value, "ttl", 1)
type = "SRV"
zone_id = var.cloudflare_zone_id
data {
name = var.cloudflare_zone_name
port = lookup(each.value, "port", 0)
priority = lookup(each.value, "priority", 0)
proto = split(".", each.key)[1]
service = split(".", each.key)[0]
target = lookup(each.value, "target", ".")
weight = lookup(each.value, "weight", 0)
}
}
```
</details>
<!-- x-release-please-end -->
<!-- prettier-ignore-start -->
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
| --------------------------------------------------------------------------- | ------------- |
| <a name="requirement_cloudflare"></a> [cloudflare](#requirement_cloudflare) | >= 3.0, < 5.0 |
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1 |
| <a name="requirement_cloudflare"></a> [cloudflare](#requirement\_cloudflare) | >= 3.0, < 5.0 |
## Providers
| Name | Version |
| --------------------------------------------------------------------- | ------------- |
| <a name="provider_cloudflare"></a> [cloudflare](#provider_cloudflare) | >= 3.0, < 5.0 |
| Name | Version |
|------|---------|
| <a name="provider_cloudflare"></a> [cloudflare](#provider\_cloudflare) | >= 3.0, < 5.0 |
## Modules
@@ -120,48 +296,50 @@ No modules.
## Resources
| Name | Type |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| [cloudflare_record.dmarc](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.domainkeys](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mta-sts-a](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mta-sts-aaaa](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mx](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.smtp_tls](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.spf](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_worker_route.mta_sts_route](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/worker_route) | resource |
| [cloudflare_worker_script.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/worker_script) | resource |
| [cloudflare_workers_kv.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/workers_kv) | resource |
| [cloudflare_workers_kv_namespace.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/workers_kv_namespace) | resource |
| [cloudflare_zone.zone](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zone) | data source |
| Name | Type |
|------|------|
| [cloudflare_record.dmarc](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.domainkeys](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mta-sts-a](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mta-sts-aaaa](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.mx](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.smtp_tls](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_record.spf](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
| [cloudflare_worker_route.mta_sts_route](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/worker_route) | resource |
| [cloudflare_worker_script.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/worker_script) | resource |
| [cloudflare_workers_kv.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/workers_kv) | resource |
| [cloudflare_workers_kv_namespace.mta_sts](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/workers_kv_namespace) | resource |
| [cloudflare_zone.zone](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zone) | data source |
## Inputs
| Name | Description | Type | Default | Required |
| ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------- | :------: |
| <a name="input_account_id"></a> [account_id](#input_account_id) | Cloudflare Account ID | `string` | n/a | yes |
| <a name="input_dmarc_dkim_mode"></a> [dmarc_dkim_mode](#input_dmarc_dkim_mode) | The DMARC DKIM mode for alignment (options: `relaxed`, `strict`). | `string` | `"relaxed"` | no |
| <a name="input_dmarc_fo"></a> [dmarc_fo](#input_dmarc_fo) | Failure reporting options for DMARC (characters: `0`, `1`, `d`, `s`, separated by `:`). | `string` | `"1:d:s"` | no |
| <a name="input_dmarc_percent"></a> [dmarc_percent](#input_dmarc_percent) | Percentage of messages to apply the DMARC policy to (0-100). | `number` | `100` | no |
| <a name="input_dmarc_policy"></a> [dmarc_policy](#input_dmarc_policy) | The DMARC policy to apply (options: `none`, `quarantine`, `reject`). | `string` | `"none"` | no |
| <a name="input_dmarc_rua"></a> [dmarc_rua](#input_dmarc_rua) | Where aggregate DMARC reports about policy violations should be sent. | `list(string)` | n/a | yes |
| <a name="input_dmarc_ruf"></a> [dmarc_ruf](#input_dmarc_ruf) | Where failure/forensic DMARC reports about policy violations should be sent. | `list(string)` | `[]` | no |
| <a name="input_dmarc_spf_mode"></a> [dmarc_spf_mode](#input_dmarc_spf_mode) | The DMARC SPF mode for alignment (options: `relaxed`, `strict`). | `string` | `"relaxed"` | no |
| <a name="input_dmarc_ttl"></a> [dmarc_ttl](#input_dmarc_ttl) | TTL for `_dmarc` DNS record. `1` is auto. Default is `1`. | `number` | `1` | no |
| <a name="input_domainkeys"></a> [domainkeys](#input_domainkeys) | Map of domain keys with name, record type (`TXT` or `CNAME`), and value. | <pre>map(object({<br> type = string<br> value = string<br> }))</pre> | `{}` | no |
| <a name="input_mta_sts_max_age"></a> [mta_sts_max_age](#input_mta_sts_max_age) | Maximum lifetime of the policy in seconds, up to 31557600, defaults to 604800 (1 week) | `number` | `604800` | no |
| <a name="input_mta_sts_mode"></a> [mta_sts_mode](#input_mta_sts_mode) | MTA policy mode, https://tools.ietf.org/html/rfc8461#section-5 | `string` | `"testing"` | no |
| <a name="input_mta_sts_mx"></a> [mta_sts_mx](#input_mta_sts_mx) | Additional permitted MX hosts for the MTA STS policy. | `list(string)` | `[]` | no |
| <a name="input_mx"></a> [mx](#input_mx) | A map representing the MX records. Key is the mail server hostname and value is the priority. | `map(number)` | n/a | yes |
| <a name="input_mx_subdomains"></a> [mx_subdomains](#input_mx_subdomains) | List of sub-domains to also apply MX records to. | `list(string)` | `[]` | no |
| <a name="input_record_ttl"></a> [record_ttl](#input_record_ttl) | TTL for DNS records. `1` is auto. Default is `1`. | `number` | `1` | no |
| <a name="input_spf_terms"></a> [spf_terms](#input_spf_terms) | List of SPF terms that should be included in the SPF TXT record. | `list(string)` | <pre>[<br> "mx",<br> "a",<br> "~all"<br>]</pre> | no |
| <a name="input_tlsrpt_rua"></a> [tlsrpt_rua](#input_tlsrpt_rua) | Locations to which aggregate TLS SMTP reports about policy violations should be sent, either `mailto:` or `https:` schema. | `list(string)` | n/a | yes |
| <a name="input_zone_id"></a> [zone_id](#input_zone_id) | Cloudflare Zone ID | `string` | n/a | yes |
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | Cloudflare Account ID | `string` | n/a | yes |
| <a name="input_dmarc_dkim_mode"></a> [dmarc\_dkim\_mode](#input\_dmarc\_dkim\_mode) | The DMARC DKIM mode for alignment (options: `relaxed`, `strict`). | `string` | `"relaxed"` | no |
| <a name="input_dmarc_fo"></a> [dmarc\_fo](#input\_dmarc\_fo) | Failure reporting options for DMARC (characters: `0`, `1`, `d`, `s`, separated by `:`). | `string` | `"1:d:s"` | no |
| <a name="input_dmarc_percent"></a> [dmarc\_percent](#input\_dmarc\_percent) | Percentage of messages to apply the DMARC policy to (0-100). | `number` | `100` | no |
| <a name="input_dmarc_policy"></a> [dmarc\_policy](#input\_dmarc\_policy) | The DMARC policy to apply (options: `none`, `quarantine`, `reject`). | `string` | `"none"` | no |
| <a name="input_dmarc_rua"></a> [dmarc\_rua](#input\_dmarc\_rua) | Where aggregate DMARC reports about policy violations should be sent. | `list(string)` | n/a | yes |
| <a name="input_dmarc_ruf"></a> [dmarc\_ruf](#input\_dmarc\_ruf) | Where failure/forensic DMARC reports about policy violations should be sent. | `list(string)` | `[]` | no |
| <a name="input_dmarc_spf_mode"></a> [dmarc\_spf\_mode](#input\_dmarc\_spf\_mode) | The DMARC SPF mode for alignment (options: `relaxed`, `strict`). | `string` | `"relaxed"` | no |
| <a name="input_dmarc_ttl"></a> [dmarc\_ttl](#input\_dmarc\_ttl) | TTL for `_dmarc` DNS record. `1` is auto. Default is `1`. | `number` | `1` | no |
| <a name="input_domainkeys"></a> [domainkeys](#input\_domainkeys) | Map of domain keys with name, record type (`TXT` or `CNAME`), and value. | <pre>map(object({<br/> type = string<br/> value = string<br/> }))</pre> | `{}` | no |
| <a name="input_mta_sts_max_age"></a> [mta\_sts\_max\_age](#input\_mta\_sts\_max\_age) | Maximum lifetime of the policy in seconds, up to 31557600, defaults to 604800 (1 week) | `number` | `604800` | no |
| <a name="input_mta_sts_mode"></a> [mta\_sts\_mode](#input\_mta\_sts\_mode) | MTA policy mode, https://tools.ietf.org/html/rfc8461#section-5 | `string` | `"testing"` | no |
| <a name="input_mta_sts_mx"></a> [mta\_sts\_mx](#input\_mta\_sts\_mx) | Additional permitted MX hosts for the MTA STS policy. | `list(string)` | `[]` | no |
| <a name="input_mx"></a> [mx](#input\_mx) | A map representing the MX records. Key is the mail server hostname and value is the priority. | `map(number)` | n/a | yes |
| <a name="input_mx_subdomains"></a> [mx\_subdomains](#input\_mx\_subdomains) | List of sub-domains to also apply MX records to. | `list(string)` | `[]` | no |
| <a name="input_record_ttl"></a> [record\_ttl](#input\_record\_ttl) | TTL for DNS records. `1` is auto. Default is `1`. | `number` | `1` | no |
| <a name="input_spf_terms"></a> [spf\_terms](#input\_spf\_terms) | List of SPF terms that should be included in the SPF TXT record. | `list(string)` | <pre>[<br/> "mx",<br/> "a",<br/> "~all"<br/>]</pre> | no |
| <a name="input_tlsrpt_rua"></a> [tlsrpt\_rua](#input\_tlsrpt\_rua) | Locations to which aggregate TLS SMTP reports about policy violations should be sent, either `mailto:` or `https:` schema. | `list(string)` | n/a | yes |
| <a name="input_zone_id"></a> [zone\_id](#input\_zone\_id) | Cloudflare Zone ID | `string` | n/a | yes |
## Outputs
| Name | Description |
| ----------------------------------------------------------------------------------------- | ------------------------------- |
| <a name="output_mta_sts_policy_url"></a> [mta_sts_policy_url](#output_mta_sts_policy_url) | URL to the MTA-STS policy file. |
| Name | Description |
|------|-------------|
| <a name="output_mta_sts_policy_url"></a> [mta\_sts\_policy\_url](#output\_mta\_sts\_policy\_url) | URL to the MTA-STS policy file. |
<!-- END_TF_DOCS -->
<!-- prettier-ignore-end -->

View File

@@ -1,16 +0,0 @@
{
"packages": {
".": {
"release-type": "simple",
"changelog-path": "CHANGELOG.md",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"draft": false,
"prerelease": false,
"extra-files": [
"README.md"
]
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

View File

@@ -1,4 +1,6 @@
terraform {
required_version = ">= 1.1"
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"