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

Add tests and more resources #7

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ jobs:
tf_docs_output_file: README.md
tf_docs_output_method: inject
tf_docs_git_push: 'true'
tf_docs_git_commit_message: 'terraform-docs: automated update action'
tf_docs_git_commit_message: 'terraform-docs: automated update action'

24 changes: 18 additions & 6 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,32 @@ jobs:
steps:
- uses: actions/checkout@master
- name: TFLint
uses: docker://wata727/tflint
uses: docker://ghcr.io/terraform-linters/tflint:v0.55.1

fmt:
name: Code Format
runs-on: ubuntu-latest
container:
image: hashicorp/terraform:latest
image: hashicorp/terraform:1.9.0
steps:
- uses: actions/checkout@master
- run: terraform fmt --recursive -check=true

test:
name: Test
runs-on: ubuntu-latest
container:
image: hashicorp/terraform:1.9.0
steps:
- uses: actions/checkout@master
- run: terraform init
- run: terraform test

validate:
name: Validate
runs-on: ubuntu-latest
container:
image: hashicorp/terraform:latest
image: hashicorp/terraform:1.9.0
steps:
- uses: actions/checkout@master
- name: Validate Code
Expand All @@ -48,18 +58,20 @@ jobs:
terraform validate
cd -
done

minimum:
name: Minimum version check
runs-on: ubuntu-latest
container:
image: hashicorp/terraform:0.13.0
image: hashicorp/terraform:1.9.0
steps:
- uses: actions/checkout@master
- name: Validate Code
env:
AWS_REGION: 'us-east-1'
TF_WARN_OUTPUT_ERRORS: 1
run: |
sed -i -e 's/>=/=/' -e 's/ \(\d\+\.\d\+\)"/ \1.0"/' versions.tf
sed -i -e 's/>=/=/' -e 's/ \(\d\+\.\d\+\)"/ \1.0"/' _versions.tf
terraform init
terraform validate -var "region=${AWS_REGION}" -var "vpc_id=vpc-123456" -var "subnets=[\"subnet-12345a\"]" -var "workers_ami_id=ami-123456" -var "cluster_ingress_cidrs=[]" -var "cluster_name=test_cluster"
terraform validate

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.terraform
.terraform.lock.hcl
70 changes: 41 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,60 @@
# terraform-aws-ses

[![Lint Status](https://github.com/DNXLabs/terraform-aws-ses/workflows/Lint/badge.svg)](https://github.com/DNXLabs/terraform-aws-ses/actions)
[![LICENSE](https://img.shields.io/github/license/DNXLabs/terraform-aws-ses)](https://github.com/DNXLabs/terraform-aws-ses/blob/master/LICENSE)

<!--- BEGIN_TF_DOCS --->

## Requirements

| Name | Version |
|------|---------|
| terraform | >= 0.13.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0.0 |

## Providers

| Name | Version |
|------|---------|
| aws | n/a |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.91.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_route53_record.amazonses_dkim_record](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_route53_record.amazonses_verification_record](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_route53_record.ses_domain_mail_from_mx](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_route53_record.ses_domain_mail_from_txt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
| [aws_ses_configuration_set.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_configuration_set) | resource |
| [aws_ses_domain_dkim.ses_domain_dkim](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_dkim) | resource |
| [aws_ses_domain_identity.ses_domain](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity) | resource |
| [aws_ses_domain_mail_from.ses_domain_mail_from](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_mail_from) | resource |
| [aws_ses_email_identity.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_email_identity) | resource |
| [aws_ses_event_destination.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_event_destination) | resource |
| [aws_ses_receipt_rule.lambda_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_receipt_rule) | resource |
| [aws_ses_receipt_rule_set.rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_receipt_rule_set) | resource |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_route53_zone.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| create\_amazonses\_verification\_record | Create route 53 verification record for ses | `bool` | `false` | no |
| create\_domain\_mail\_from | Messages sent through Amazon SES will be marked as originating from your domain instead of a subdomain of amazon.com. | `bool` | `true` | no |
| create\_domain\_mail\_from\_mx | Create route53 MX record | `bool` | `false` | no |
| create\_domain\_mail\_from\_txt | Create route 53 TXT record | `bool` | `false` | no |
| domain | The domain name to assign to SES | `string` | n/a | yes |
| is\_route53 | Enable or disable route53 zone retriever | `bool` | `true` | no |
| <a name="input_configuration_sets"></a> [configuration\_sets](#input\_configuration\_sets) | Configuration Sets for SES | <pre>list(object({<br/> name = string<br/> redirect_domain = string<br/> }))</pre> | `[]` | no |
| <a name="input_create_amazonses_verification_record"></a> [create\_amazonses\_verification\_record](#input\_create\_amazonses\_verification\_record) | Create route 53 verification record for ses | `bool` | `false` | no |
| <a name="input_create_domain_mail_from"></a> [create\_domain\_mail\_from](#input\_create\_domain\_mail\_from) | Messages sent through Amazon SES will be marked as originating from your domain instead of a subdomain of amazon.com. | `bool` | `true` | no |
| <a name="input_create_domain_mail_from_mx"></a> [create\_domain\_mail\_from\_mx](#input\_create\_domain\_mail\_from\_mx) | Create route53 MX record | `bool` | `false` | no |
| <a name="input_create_domain_mail_from_txt"></a> [create\_domain\_mail\_from\_txt](#input\_create\_domain\_mail\_from\_txt) | Create route 53 TXT record | `bool` | `false` | no |
| <a name="input_domain"></a> [domain](#input\_domain) | The domain name to assign to SES | `string` | n/a | yes |
| <a name="input_email_identities"></a> [email\_identities](#input\_email\_identities) | n/a | `list(string)` | `[]` | no |
| <a name="input_event_destinations"></a> [event\_destinations](#input\_event\_destinations) | Event destinations for SES | <pre>list(object({<br/> name = string<br/> configuration_set_name = string<br/> enabled = optional(bool, true)<br/> matching_types = list(string)<br/> sns_destination = optional(any, [])<br/> }))</pre> | `[]` | no |
| <a name="input_is_route53"></a> [is\_route53](#input\_is\_route53) | Enable or disable route53 zone retriever | `bool` | `true` | no |
| <a name="input_receipt_rule_sets"></a> [receipt\_rule\_sets](#input\_receipt\_rule\_sets) | n/a | `list(string)` | `[]` | no |
| <a name="input_receipt_rules"></a> [receipt\_rules](#input\_receipt\_rules) | n/a | <pre>list(object({<br/> name = string<br/> rule_set_name = string<br/> enabled = bool<br/> recipients = list(string)<br/> lambda_actions = optional(list(object({<br/> function_arn = string<br/> position = number<br/> invocation_type = string<br/> })), [])<br/> s3_actions = optional(list(object({<br/> position = number<br/> bucket_name = string<br/> })), [])<br/> stop_actions = optional(list(object({<br/> position = number<br/> scope = string<br/> })), [])<br/> }))</pre> | `[]` | no |

## Outputs

| Name | Description |
|------|-------------|
| amazonses\_dkim\_record | n/a |
| amazonses\_verification\_record | n/a |
| ses\_domain\_mail\_from\_mx | n/a |
| ses\_domain\_mail\_from\_txt | n/a |

<!--- END_TF_DOCS --->

## Authors

Module managed by [DNX Solutions](https://github.com/DNXLabs).

## License

Apache 2 Licensed. See [LICENSE](https://github.com/DNXLabs/terraform-aws-template/blob/master/LICENSE) for full details.
| <a name="output_amazonses_dkim_record"></a> [amazonses\_dkim\_record](#output\_amazonses\_dkim\_record) | n/a |
| <a name="output_amazonses_verification_record"></a> [amazonses\_verification\_record](#output\_amazonses\_verification\_record) | n/a |
| <a name="output_ses_domain_mail_from_mx"></a> [ses\_domain\_mail\_from\_mx](#output\_ses\_domain\_mail\_from\_mx) | n/a |
| <a name="output_ses_domain_mail_from_txt"></a> [ses\_domain\_mail\_from\_txt](#output\_ses\_domain\_mail\_from\_txt) | n/a |
7 changes: 4 additions & 3 deletions _data.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
data "aws_region" "current" {}

data "aws_route53_zone" "main" {
count = var.is_route53 == false ? 0 : 1
name = var.domain
}
for_each = { for domain in var.domain_identities : domain.domain => domain }
name = each.key
}

4 changes: 4 additions & 0 deletions _locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
locals {
valid_matching_types = ["send", "reject", "bounce", "complaint", "delivery", "open", "click", "renderingFailure"]
}

6 changes: 3 additions & 3 deletions _outputs.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
output "amazonses_dkim_record" {
# value = join("", aws_ses_domain_dkim.ses_domain_dkim.dkim_tokens) + ".dkim.amazonses.com"
value = aws_ses_domain_dkim.ses_domain_dkim
}

output "amazonses_verification_record" {
value = join("", aws_ses_domain_identity.ses_domain.*.verification_token)
value = aws_ses_domain_identity.ses_domain[*]
}

output "ses_domain_mail_from_mx" {
Expand All @@ -13,4 +12,5 @@ output "ses_domain_mail_from_mx" {

output "ses_domain_mail_from_txt" {
value = ["v=spf1 include:amazonses.com ~all"]
}
}

96 changes: 73 additions & 23 deletions _variables.tf
Original file line number Diff line number Diff line change
@@ -1,34 +1,84 @@
variable "domain" {
type = string
variable "domain_identities" {
type = list(object({
domain = string
is_route53 = optional(bool, true)
create_domain_mail_from = optional(bool, true)
create_verification_record = optional(bool, true)
create_domain_mail_from_mx = optional(bool, true)
create_domain_mail_from_txt = optional(bool, true)
}))
description = "The domain name to assign to SES"
}

variable "create_domain_mail_from" {
type = bool
description = "Messages sent through Amazon SES will be marked as originating from your domain instead of a subdomain of amazon.com."
default = true
variable "email_identities" {
type = list(string)
description = ""
default = []
}

variable "create_domain_mail_from_mx" {
type = bool
description = "Create route53 MX record"
default = false
variable "configuration_sets" {
type = list(object({
name = string
redirect_domain = string
}))
description = "Configuration Sets for SES"
default = []
# TO-DO: Add validation for delivery_options.tls_policy. Can be Optional or Require
}

variable "create_domain_mail_from_txt" {
type = bool
description = "Create route 53 TXT record"
default = false
variable "event_destinations" {
type = list(object({
name = string
configuration_set_name = string
enabled = optional(bool, true)
matching_types = list(string)
sns_destination = optional(any, [])
}))
description = "Event destinations for SES"
default = []

validation {
error_message = "Invalid value for matching_types. Should be one of: send, reject, bounce, complaint, delivery, open, click or renderingFailure"
condition = alltrue([
for event in var.event_destinations : alltrue([
for type in event.matching_types : contains(local.valid_matching_types, type)
])
])
}
validation {
error_message = "Invalid configuration_set_name."
condition = alltrue([
for event in var.event_destinations : contains(flatten([for config_set in var.configuration_sets : config_set.name]), event.configuration_set_name)
])
}
}

variable "receipt_rule_sets" {
type = list(string)
default = []
}

variable "create_amazonses_verification_record" {
type = bool
description = "Create route 53 verification record for ses"
default = false
variable "receipt_rules" {
type = list(object({
name = string
rule_set_name = string
enabled = bool
recipients = list(string)
lambda_actions = optional(list(object({
function_arn = string
position = number
invocation_type = string
})), [])
s3_actions = optional(list(object({
position = number
bucket_name = string
})), [])
stop_actions = optional(list(object({
position = number
scope = string
})), [])
}))
default = []
# TO-DO: Add validation if rule_set_name exists
}

variable "is_route53" {
type = bool
description = "Enable or disable route53 zone retriever"
default = true
}
10 changes: 10 additions & 0 deletions _versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.9.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0.0"
}
}
}

12 changes: 12 additions & 0 deletions configuration_set.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
resource "aws_ses_configuration_set" "default" {
for_each = { for config in var.configuration_sets : config.name => config }
name = each.value.name
reputation_metrics_enabled = false
sending_enabled = true
delivery_options {
tls_policy = "Require"
}
tracking_options {
custom_redirect_domain = each.value.redirect_domain
}
}
14 changes: 14 additions & 0 deletions event_destination.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "aws_ses_event_destination" "default" {
for_each = { for event in var.event_destinations : event.name => event }
name = each.value.name
configuration_set_name = aws_ses_configuration_set.default[each.value.configuration_set_name].name
enabled = true
matching_types = each.value.matching_types
dynamic "sns_destination" {
for_each = each.value.sns_destination
content {
topic_arn = aws_sns_topic.sns[sns_destination.value["name"]].arn
}
}
depends_on = [aws_ses_configuration_set.default]
}
36 changes: 36 additions & 0 deletions receipt_rules.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
resource "aws_ses_receipt_rule_set" "rule" {
for_each = { for sets in var.receipt_rule_sets : sets.name => sets }
rule_set_name = each.key
}

resource "aws_ses_receipt_rule" "lambda_rule" {
for_each = { for receipt_rule in var.receipt_rules : receipt_rule.name => receipt_rule }
name = each.value.name
rule_set_name = each.value.rule_set_name
enabled = each.value.enabled
recipients = each.value.recipients
scan_enabled = true

dynamic "lambda_action" {
for_each = each.value.lambda_actions
content {
function_arn = lambda_action.value.function_arn
position = lambda_action.value.position
invocation_type = lambda_action.value.invocation_type
}
}
dynamic "s3_action" {
for_each = each.value.s3_actions
content {
position = s3_action.value.position
bucket_name = s3_action.value.bucket_name
}
}
dynamic "stop_action" {
for_each = each.value.stop_actions
content {
position = stop_action.value.position
scope = stop_action.value.scope
}
}
}
Loading
Loading