diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index b71d691..6f20ddd 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
- rev: v1.47.0
+ rev: v1.48.0
hooks:
# - id: terraform_validate
- id: terraform_fmt
@@ -8,9 +8,10 @@ repos:
args: ['table']
exclude: common/*.tf
exclude: version.tf
-
+ - id: terraform_tflint
+ args: [ "--args=--config=__GIT_WORKING_DIR__/.tflint.hcl"]
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v3.1.0
+ rev: v3.4.0
hooks:
- id: check-symlinks
- id: detect-aws-credentials
diff --git a/.tflint.hcl b/.tflint.hcl
new file mode 100644
index 0000000..fcc2fa8
--- /dev/null
+++ b/.tflint.hcl
@@ -0,0 +1,21 @@
+config {
+ module = true
+ force = false
+ disabled_by_default = false
+
+# ignore_module = {
+# "terraform-aws-modules/vpc/aws" = true
+# "terraform-aws-modules/security-group/aws" = true
+# }
+
+# varfile = ["example1.tfvars", "example2.tfvars"]
+# variables = ["foo=bar", "bar=[\"baz\"]"]
+}
+
+rule "aws_instance_invalid_type" {
+ enabled = true
+}
+
+plugin "aws" {
+ enabled = true
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eef7c92..74faa1d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,3 +43,7 @@
* v1.7.3 -- 20210324
- iam-general-policies
- fix bad arn
+
+* v1.7.4 -- 20210326
+ - ses-domain
+ - add code to enable move to production, runs aws cli script
diff --git a/common/version.tf b/common/version.tf
index 19a45aa..4d1d42c 100644
--- a/common/version.tf
+++ b/common/version.tf
@@ -1,3 +1,3 @@
locals {
- _module_version = "1.7.3"
+ _module_version = "1.7.4"
}
diff --git a/ses-domain/README.md b/ses-domain/README.md
index 12649bd..bcf41ed 100644
--- a/ses-domain/README.md
+++ b/ses-domain/README.md
@@ -1,20 +1,21 @@
# aws-inf-setup :: ses-domain
-This sets up the domain identity for SES. We create by default `{account_id}.aws.mail.census.gov`
-as a sender domain, and generate the details which are to be submitted to TCO for inclusion in DNS.
-The contents of the file `${path.root}/setup/ses_dns.md` contain the text which goes to TCO. A future enhancement
-to this will include the ability to automatically incorporate the changes into DNS. This is a multi-step
+This sets up the domain identity for SES. We create by default `{account_id}.aws.mail.census.gov`
+as a sender domain, and generate the details which are to be submitted to TCO for inclusion in DNS.
+The contents of the file `${path.root}/setup/ses_dns.md` contain the text which goes to TCO. A future enhancement
+to this will include the ability to automatically incorporate the changes into DNS. This is a multi-step
setup:
-1. Create initial resources
-1. Provide TCO Details for DNS Update
+1. Create initial resources
+1. Provide TCO Details for DNS Update
1. Complete domain validation
+1. Enable for production
## Select proper region
-Note that at this time, this needs to be done from the `us-gov-west-1` region for GovCloud. For East/West, any US region
-will work. Ideally, this will check that the west zone is selected for gov, and not create any resources if in the incorrect region.
-However, that's not current possible with Terraform 0.12, and we need to get to 0.13 to make that possible. You will see this
+Note that at this time, this needs to be done from the `us-gov-west-1` region for GovCloud. For East/West, any US region
+will work. Ideally, this will check that the west zone is selected for gov, and not create any resources if in the incorrect region.
+However, that's not current possible with Terraform 0.12, and we need to get to 0.13 to make that possible. You will see this
error if in the incorrect region:
```console
% tf-apply
@@ -29,17 +30,21 @@ Error: Error requesting SES domain identity verification: SignatureDoesNotMatch:
## Request TCO/OIS approval for 3rd Party Domain
-A submission of a form authorizing 3rd party mail is required to TCO, who then puts in a ticket to OIS. This has
+A submission of a form authorizing 3rd party mail is required to TCO, who then puts in a ticket to OIS. This has
been done for the AWS accounts as whole, using the default format. Any variation (that is, using a custom
`ses_domain_name` requires this form be filled out. Details are available on the [TCO Wiki Mail Section](https://wiki.apps.tco.census.gov/index.php/Services#Mail) or in [Sending Mail](https://wiki.apps.tco.census.gov/index.php/Sending_Mail).
-# Usage
+# Usage
This can be used without any variables to get the default configuration.
```hcl
module "ses" {
source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ses-domain"
+ profile = var.profile
+ ## once validated, get out of sandbox
+ # ses_enable_production = true
+
## optional, changing this is not recommended
# ses_domain_name = "123456789012.postal.census.gov"
## while these can be changed, it is not advised
@@ -56,8 +61,8 @@ module "ses" {
See and example [ses\_dns.md](example.ses\_dns.md). This file will be in `setup/ses_dns.md`. Submit this to TCO to get the records added to DNS.
-## After DNS is updated
-Once DNS has been updated, you can run `tf-apply` on the resource again. It will look for a non-empty value
+## After DNS is updated
+Once DNS has been updated, you can run `tf-apply` on the resource again. It will look for a non-empty value
for the TXT record and if so, complete the validation process. Here is an example:
```console
% tf-apply -target=module.ses
@@ -76,6 +81,35 @@ Plan: 1 to add, 0 to change, 0 to destroy.
module.ses.aws_ses_domain_identity_verification.this[0]: Creating...
module.ses.aws_ses_domain_identity_verification.this[0]: Creation complete after 1s [id=817869416306.aws.mail.census.gov]
```
+## Getting out of the Sandbox
+Reference: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html
+
+Use the variable `ses_enable_production=true` to do this. There is no terraform resource for this.
+This enables the use of a script which requires the AWS CLIv2, and it will fail otherwise.
+
+```hcl
+module "ses" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ses-domain"
+
+ profile = var.profile
+ ses_enable_production = true
+}
+```
+then run `tf-apply`
+```console
+% tf-apply -target=module.ses
+Resource actions are indicated with the following symbols:
+-/+ destroy and then create replacement
+
+Terraform will perform the following actions:
+
+ # module.ses.null_resource.to_production[0] is tainted, so must be replaced
+-/+ resource "null_resource" "to_production" {
+ ~ id = "283142555786980861" -> (known after apply)
+ }
+
+Plan: 1 to add, 0 to change, 1 to destroy.
+```
# Sample Output
```hcl
@@ -110,8 +144,6 @@ ses_domain_verification = {
"value" = "/Pz6+wpIUfumhdG8l0NkdfLx+wHMp+/Za2Nf5jOQTos="
}
```
-# Getting out of the Sandbox
-Refence: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html
## Requirements
@@ -121,44 +153,51 @@ No requirements.
| Name | Version |
|------|---------|
-| aws | n/a |
-| external | n/a |
-| null | n/a |
+| [aws](#provider\_aws) | n/a |
+| [external](#provider\_external) | n/a |
+| [null](#provider\_null) | n/a |
## Modules
-No Modules.
+No modules.
## Resources
-| Name |
-|------|
-| [aws_arn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) |
-| [aws_caller_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) |
-| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) |
-| [aws_ses_domain_dkim](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_dkim) |
-| [aws_ses_domain_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity) |
-| [aws_ses_domain_identity_verification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity_verification) |
-| [external_external](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) |
-| [null_resource](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) |
+| Name | Type |
+|------|------|
+| [aws_ses_domain_dkim.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_dkim) | resource |
+| [aws_ses_domain_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity) | resource |
+| [aws_ses_domain_identity_verification.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ses_domain_identity_verification) | resource |
+| [null_resource.this_output](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
+| [null_resource.to_production](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
+| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
+| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
+| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
+| [external_external.ses_dns_txt](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
-| account\_alias | AWS Account Alias | `string` | `""` | no |
-| account\_id | AWS Account ID (default will pull from current user) | `string` | `""` | no |
-| override\_prefixes | Override built-in prefixes by component (efs, s3, ebs, kms, role, policy, security-group). This should be used primarily for common infrastructure things | `map(string)` | `{}` | no |
-| ses\_base\_dkim\_domain\_name | SES Base DKIM Domain Name | `string` | `"dkim.amazonses.com"` | no |
-| ses\_base\_domain\_name | SES Base Domain Name | `string` | `"aws.mail.census.gov"` | no |
-| ses\_domain\_name | SES Fully Qualified Domain Name (default: {account\_id}.aws.mail.census.gov) | `string` | `""` | no |
-| tags | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
+| [account\_alias](#input\_account\_alias) | AWS Account Alias | `string` | `""` | no |
+| [account\_id](#input\_account\_id) | AWS Account ID (default will pull from current user) | `string` | `""` | no |
+| [override\_prefixes](#input\_override\_prefixes) | Override built-in prefixes by component (efs, s3, ebs, kms, role, policy, security-group). This should be used primarily for common infrastructure things | `map(string)` | `{}` | no |
+| [profile](#input\_profile) | AWS Config profile (required for calling the aws cli) | `string` | `""` | no |
+| [region](#input\_region) | AWS Region (default takes from current executing region) | `string` | `""` | no |
+| [ses\_additional\_contact\_email](#input\_ses\_additional\_contact\_email) | SES Additional Contact email address list (for move to production) | `list(string)` | `[]` | no |
+| [ses\_base\_dkim\_domain\_name](#input\_ses\_base\_dkim\_domain\_name) | SES Base DKIM Domain Name | `string` | `"dkim.amazonses.com"` | no |
+| [ses\_base\_domain\_name](#input\_ses\_base\_domain\_name) | SES Base Domain Name | `string` | `"aws.mail.census.gov"` | no |
+| [ses\_domain\_name](#input\_ses\_domain\_name) | SES Fully Qualified Domain Name (default: {account\_id}.aws.mail.census.gov) | `string` | `""` | no |
+| [ses\_enable\_production](#input\_ses\_enable\_production) | SES Enable calling of AWS CLI to move from sandbox to production | `bool` | `false` | no |
+| [ses\_use\_case\_description](#input\_ses\_use\_case\_description) | SES use case description (for move to production) | `string` | `""` | no |
+| [ses\_website\_url](#input\_ses\_website\_url) | SES website URL (for move to production) | `string` | `"https://census.gov"` | no |
+| [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
## Outputs
| Name | Description |
|------|-------------|
-| ses\_dkim\_values | DNS entries to add for DKIM |
-| ses\_domain\_identity | SES Domain Identity |
-| ses\_domain\_identity\_arn | SES Domain Identity ARN |
-| ses\_domain\_verification | DNS entries to add for domain verification |
+| [ses\_dkim\_values](#output\_ses\_dkim\_values) | DNS entries to add for DKIM |
+| [ses\_domain\_identity](#output\_ses\_domain\_identity) | SES Domain Identity |
+| [ses\_domain\_identity\_arn](#output\_ses\_domain\_identity\_arn) | SES Domain Identity ARN |
+| [ses\_domain\_verification](#output\_ses\_domain\_verification) | DNS entries to add for domain verification |
diff --git a/ses-domain/bin/move-to-production.sh b/ses-domain/bin/move-to-production.sh
old mode 100644
new mode 100755
index 2ffd271..6ee3bcb
--- a/ses-domain/bin/move-to-production.sh
+++ b/ses-domain/bin/move-to-production.sh
@@ -12,38 +12,54 @@ $AWS sesv2 help >/dev/null 2>&1
status=$?
if [ $status != 0 ]
then
- echo "* aws sesv2 CLI missing"
+ echo "* aws sesv2 CLI missing or error with profile/region status=$status"
exit 1
fi
-if [[ -z $AWS_PROFILE ]] || [[ -z $AWS_DEFAULT_REGION ]
+if [[ -z $AWS_PROFILE ]] || [[ -z $AWS_DEFAULT_REGION ]]
then
- echo "* missing AWS_PROFILE=$AWS_PROFILE or AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION"
+ echo "* missing AWS_PROFILE='$AWS_PROFILE' or AWS_DEFAULT_REGION='$AWS_DEFAULT_REGION'"
exit 1
fi
if [ -z $SES_USE_CASE_DESCRIPTION ]
then
- SES_USE_CASE_DESCRIPTION="Used for alerting and notification from lambda and other applications to users within our own enterprise mail system"
+ SES_USE_CASE_DESCRIPTION="Used for alerting and notification from lambda and other applications to users registered within our own enterprise mail system."
fi
if [ -z $SES_ADDITIONAL_CONTACT_EMAIL ]
then
- SES_ADDITIONAL_CONTACT_EMAIL="donald.e.badrak.ii@census.gov,roy.d.ashley.jr@census.gov"
+ SES_ADDITIONAL_CONTACT_EMAIL="donald.e.badrak.ii@census.gov roy.d.ashley.jr@census.gov"
fi
-$AWS sesv2 put-account-details \
---production-access-enabled \
---mail-type TRANSACTIONAL \
---use-case-description "$SES_USE_CASE_DESCRIPTION" \
---additional-contact-email-addresses "$SES_ADDITIONAL_CONTACT_EMAIL" \
---contact-language EN
+if [ -z $SES_WEBSITE_URL ]
+then
+ SES_WEBSITE_URL="https://census.gov"
+fi
+
+if [ ! -z $SES_DEBUG ]
+then
+ SES_DEBUG="true"
+fi
+
+$SES_DEBUG $AWS sesv2 put-account-details \
+ --production-access-enabled \
+ --mail-type TRANSACTIONAL \
+ --website-url "$SES_WEBSITE_URL" \
+ --use-case-description "$SES_USE_CASE_DESCRIPTION" \
+ --additional-contact-email-addresses $SES_ADDITIONAL_CONTACT_EMAIL \
+ --contact-language EN
status=$?
if [ $status != 0 ]
then
echo "* error requesting production access for SES"
+ exit $status
fi
+
+# now, get the details
+$SES_DEBUG $AWS sesv2 get-account
+
exit $status
# unused options
@@ -54,3 +70,4 @@ exit $status
# AWS_PROFILE
# SES_ADDITIONAL_CONTACT_EMAIL
# SES_USE_CASE_DESCRIPTION
+# SES_WEBSITE_URL
diff --git a/ses-domain/main.tf b/ses-domain/main.tf
index f566a72..29273d3 100644
--- a/ses-domain/main.tf
+++ b/ses-domain/main.tf
@@ -10,6 +10,7 @@
* 1. Create initial resources
* 1. Provide TCO Details for DNS Update
* 1. Complete domain validation
+* 1. Enable for production
*
* ## Select proper region
*
@@ -41,6 +42,10 @@
* module "ses" {
* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ses-domain"
*
+* profile = var.profile
+* ## once validated, get out of sandbox
+* # ses_enable_production = true
+*
* ## optional, changing this is not recommended
* # ses_domain_name = "123456789012.postal.census.gov"
* ## while these can be changed, it is not advised
@@ -77,6 +82,35 @@
* module.ses.aws_ses_domain_identity_verification.this[0]: Creating...
* module.ses.aws_ses_domain_identity_verification.this[0]: Creation complete after 1s [id=817869416306.aws.mail.census.gov]
* ```
+* ## Getting out of the Sandbox
+* Reference: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html
+*
+* Use the variable `ses_enable_production=true` to do this. There is no terraform resource for this.
+* This enables the use of a script which requires the AWS CLIv2, and it will fail otherwise.
+*
+* ```hcl
+* module "ses" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ses-domain"
+*
+* profile = var.profile
+* ses_enable_production = true
+* }
+* ```
+* then run `tf-apply`
+* ```console
+* % tf-apply -target=module.ses
+* Resource actions are indicated with the following symbols:
+* -/+ destroy and then create replacement
+*
+* Terraform will perform the following actions:
+*
+* # module.ses.null_resource.to_production[0] is tainted, so must be replaced
+* -/+ resource "null_resource" "to_production" {
+* ~ id = "283142555786980861" -> (known after apply)
+* }
+*
+* Plan: 1 to add, 0 to change, 1 to destroy.
+* ```
*
* # Sample Output
* ```hcl
@@ -111,8 +145,6 @@
* "value" = "/Pz6+wpIUfumhdG8l0NkdfLx+wHMp+/Za2Nf5jOQTos="
* }
* ```
-* # Getting out of the Sandbox
-* Refence: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/request-production-access.html
*/
locals {
@@ -183,3 +215,22 @@ resource "null_resource" "this_output" {
command = "echo '${local.ses_output}' > setup/ses_dns.md"
}
}
+
+resource "null_resource" "to_production" {
+ count = var.ses_enable_production ? 1 : 0
+ triggers = {
+ contact_email = length(var.ses_additional_contact_email) > 0 ? join(" ", var.ses_additional_contact_email) : ""
+ use_case = var.ses_use_case_description
+ website_url = var.ses_website_url
+ }
+ provisioner "local-exec" {
+ command = "${path.module}/bin/move-to-production.sh"
+ environment = {
+ AWS_DEFAULT_REGION = var.region == "" ? data.aws_region.current.name : var.region
+ AWS_PROFILE = var.profile == "" ? "default" : var.profile
+ SES_ADDITIONAL_CONTACT_EMAIL = length(var.ses_additional_contact_email) > 0 ? join(" ", var.ses_additional_contact_email) : ""
+ SES_USE_CASE_DESCRIPTION = var.ses_use_case_description
+ SES_WEBSITE_URL = var.ses_website_url
+ }
+ }
+}
diff --git a/ses-domain/variables.tf b/ses-domain/variables.tf
index 3f0911b..6f517e6 100644
--- a/ses-domain/variables.tf
+++ b/ses-domain/variables.tf
@@ -1,3 +1,9 @@
+# variable "component_tags" {
+# description = "Additional tags for Components (s3, kms, ddb)"
+# type = map(map(string))
+# default = { "s3" = {}, "kms" = {}, "ddb" = {} }
+# }
+
variable "ses_domain_name" {
description = "SES Fully Qualified Domain Name (default: {account_id}.aws.mail.census.gov)"
type = string
@@ -16,8 +22,38 @@ variable "ses_base_dkim_domain_name" {
default = "dkim.amazonses.com"
}
-# variable "component_tags" {
-# description = "Additional tags for Components (s3, kms, ddb)"
-# type = map(map(string))
-# default = { "s3" = {}, "kms" = {}, "ddb" = {} }
-# }
+variable "ses_enable_production" {
+ description = "SES Enable calling of AWS CLI to move from sandbox to production"
+ type = bool
+ default = false
+}
+
+variable "ses_additional_contact_email" {
+ description = "SES Additional Contact email address list (for move to production)"
+ type = list(string)
+ default = []
+}
+
+variable "ses_use_case_description" {
+ description = "SES use case description (for move to production)"
+ type = string
+ default = ""
+}
+
+variable "ses_website_url" {
+ description = "SES website URL (for move to production)"
+ type = string
+ default = "https://census.gov"
+}
+
+variable "region" {
+ description = "AWS Region (default takes from current executing region)"
+ type = string
+ default = ""
+}
+
+variable "profile" {
+ description = "AWS Config profile (required for calling the aws cli)"
+ type = string
+ default = ""
+}