Skip to content

Commit

Permalink
Custom domain sub module added (#5)
Browse files Browse the repository at this point in the history
* Refactoring the variables to map

* Custom domain module added

* pre-commit fixes

* added example for variable

* enforce TLS1.2

* tf fmt

* pre-commit fixes

* typo fixed and map updated

* ACM Cert provisioning

* remove the extra new line

Co-authored-by: pre-commit <[email protected]>
  • Loading branch information
pkailasu and pre-commit authored May 13, 2022
1 parent 8f230e5 commit 9aea20f
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 31 deletions.
49 changes: 38 additions & 11 deletions examples/apigw_with_usage_plan/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,43 @@ module "api_gateway_usage_plan" {

name = "PetStoreSandbox-usage-plan"

stages = [
{
"stage" : module.api_gateway.aws_api_gateway_stage_name,
"api_id" : module.api_gateway.aws_api_gateway_rest_api_id
stages = {
stage1 = {
stage = module.api_gateway.aws_api_gateway_stage_name
api_id = module.api_gateway.aws_api_gateway_rest_api_id
}
]
api_keys = [
{ "key_name" : "key1", "enabled" : true },
{ "key_name" : "key2", "enabled" : true },
{ "key_name" : "key3", "enabled" : false },
{ "key_name" : "key4", "enabled" : true },
]
}
api_keys = {
key1 = {
key_name = "key1"
enabled = true
}
key2 = {
key_name = "key2"
enabled = true
}
key3 = {
key_name = "key3",
enabled = false
}
key4 = {
key_name = "key4",
enabled = true
}
}
}

module "api_gateway_custom_domain" {
source = "../../../terraform-aws-apigw/modules/custom_domain"

domain_name = "petstore-apitest.sphdigital.com"
create_acm_cert = true

path_mappings = {
v1 = {
stage_name = module.api_gateway.aws_api_gateway_stage_name
api_id = module.api_gateway.aws_api_gateway_rest_api_id
base_path = "v1"
}
}
}
50 changes: 50 additions & 0 deletions modules/custom_domain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Custom domain name for API Gateway

Provides custom domain name resource for the API Gateway and the mapping of domain name to the api.

Supports only REGIONAL endpoint for now.

Provisions option to create ACM certifcation. Cert validation needs to be done offline.

<!-- BEGIN_TF_DOCS -->
## Requirements

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

## Providers

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

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_acm_certificate.cert](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |
| [aws_api_gateway_base_path_mapping.mapping](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_base_path_mapping) | resource |
| [aws_api_gateway_domain_name.domain](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_domain_name) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cert_arn"></a> [cert\_arn](#input\_cert\_arn) | Cert ARN. Create ACM cert. create\_acm\_cert and cert\_arn Mutually exclusive. | `string` | `""` | no |
| <a name="input_create_acm_cert"></a> [create\_acm\_cert](#input\_create\_acm\_cert) | Create ACM cert. create\_acm\_cert and cert\_arn Mutually exclusive. | `bool` | `false` | no |
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Custom domain name | `string` | n/a | yes |
| <a name="input_path_mappings"></a> [path\_mappings](#input\_path\_mappings) | List of stages the usage plan can be used | <pre>map(<br> object({<br> api_id = string<br> stage_name = string<br> base_path = string<br> })<br> )</pre> | n/a | yes |
| <a name="input_security_policy"></a> [security\_policy](#input\_security\_policy) | TLS Security Policy for the domain | `string` | `"TLS_1_2"` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | ARN of domain name. |
<!-- END_TF_DOCS -->
31 changes: 31 additions & 0 deletions modules/custom_domain/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Provisioned only for regional types. @todo: Enhance for other types as well
resource "aws_api_gateway_domain_name" "domain" {
domain_name = var.domain_name
regional_certificate_arn = var.cert_arn == "" ? aws_acm_certificate.cert[0].arn : var.cert_arn
security_policy = var.security_policy

endpoint_configuration {
types = ["REGIONAL"]
}

}

resource "aws_api_gateway_base_path_mapping" "mapping" {
for_each = var.path_mappings

api_id = each.value.api_id
stage_name = each.value.stage_name
base_path = each.value.base_path
domain_name = aws_api_gateway_domain_name.domain.domain_name
}

resource "aws_acm_certificate" "cert" {
count = var.create_acm_cert && var.cert_arn == "" ? 1 : 0

domain_name = var.domain_name
validation_method = "DNS"

lifecycle {
create_before_destroy = true
}
}
4 changes: 4 additions & 0 deletions modules/custom_domain/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "arn" {
value = aws_api_gateway_domain_name.domain.arn
description = "ARN of domain name."
}
37 changes: 37 additions & 0 deletions modules/custom_domain/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
################################################################################
# variables for Custom domain mapping sub module
################################################################################

variable "domain_name" {
description = "Custom domain name"
type = string
}

variable "security_policy" {
description = "TLS Security Policy for the domain"
type = string
default = "TLS_1_2"
}

variable "create_acm_cert" {
description = "Create ACM cert. create_acm_cert and cert_arn Mutually exclusive. "
type = bool
default = false
}

variable "cert_arn" {
description = "Cert ARN. Create ACM cert. create_acm_cert and cert_arn Mutually exclusive."
type = string
default = ""
}

variable "path_mappings" {
description = "List of stages the usage plan can be used "
type = map(
object({
api_id = string
stage_name = string
base_path = string
})
)
}
9 changes: 9 additions & 0 deletions modules/custom_domain/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
5 changes: 3 additions & 2 deletions modules/usage_plan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_api_keys"></a> [api\_keys](#input\_api\_keys) | List of api keys created and assigned to the usage plan | `list(any)` | `[]` | no |
| <a name="input_api_keys"></a> [api\_keys](#input\_api\_keys) | List of api keys created and assigned to the usage plan | <pre>map(<br> object({<br> key_name = string<br> enabled = bool<br> })<br> )</pre> | `{}` | no |
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | Default Tags for Auto Scaling Group | `map(string)` | `{}` | no |
| <a name="input_limit"></a> [limit](#input\_limit) | The maximum number of requests that can be made in a given time period. | `number` | `5000` | no |
| <a name="input_name"></a> [name](#input\_name) | Usage plan name | `string` | n/a | yes |
| <a name="input_offset"></a> [offset](#input\_offset) | The number of requests subtracted from the given limit in the initial time period. | `number` | `2` | no |
| <a name="input_period"></a> [period](#input\_period) | The time period in which the limit applies. Valid values are DAY, WEEK or MONTH. | `string` | `"MONTH"` | no |
| <a name="input_stages"></a> [stages](#input\_stages) | List of stages the usage plan can be used | `list(any)` | n/a | yes |
| <a name="input_quota_settings_unlimited"></a> [quota\_settings\_unlimited](#input\_quota\_settings\_unlimited) | Specifies whether there is a unlimited quota limit . | `bool` | `false` | no |
| <a name="input_stages"></a> [stages](#input\_stages) | List of stages the usage plan can be used | <pre>map(<br> object({<br> api_id = string<br> stage = string<br> })<br> )</pre> | n/a | yes |

## Outputs

Expand Down
28 changes: 14 additions & 14 deletions modules/usage_plan/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ resource "aws_api_gateway_usage_plan" "usage_plan" {
description = "Usage plan created for ${var.name}"

dynamic "api_stages" {
for_each = [for s in var.stages : {
api_id = s.api_id
stage = s.stage
}]
for_each = var.stages

content {
api_id = api_stages.value.api_id
Expand All @@ -15,10 +12,13 @@ resource "aws_api_gateway_usage_plan" "usage_plan" {

}

quota_settings {
limit = var.limit
offset = var.offset
period = var.period
dynamic "quota_settings" {
for_each = var.quota_settings_unlimited == true ? [1] : []
content {
limit = var.limit
offset = var.offset
period = var.period
}
}

tags = {
Expand All @@ -27,22 +27,22 @@ resource "aws_api_gateway_usage_plan" "usage_plan" {
}

resource "aws_api_gateway_api_key" "key" {
for_each = { for api_key in var.api_keys : api_key.key_name => api_key }
for_each = var.api_keys

name = each.key
description = "API Key for ${each.key}"
name = each.value.key_name
description = "API Key for ${each.value.key_name}"
enabled = each.value.enabled

tags = {
Name = each.key
Name = each.value.key_name
}

}

resource "aws_api_gateway_usage_plan_key" "main" {
for_each = { for api_key in var.api_keys : api_key.key_name => api_key }
for_each = var.api_keys

key_id = aws_api_gateway_api_key.key[each.key].id
key_id = aws_api_gateway_api_key.key[each.value.key_name].id
key_type = "API_KEY"
usage_plan_id = aws_api_gateway_usage_plan.usage_plan.id
}
22 changes: 18 additions & 4 deletions modules/usage_plan/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@ variable "default_tags" {

variable "stages" {
description = "List of stages the usage plan can be used "
type = list(any)
type = map(
object({
api_id = string
stage = string
})
)
}

variable "quota_settings_unlimited" {
description = "Specifies whether there is a unlimited quota limit ."
type = bool
default = false
}

variable "limit" {
description = "The maximum number of requests that can be made in a given time period."
Expand All @@ -40,7 +50,11 @@ variable "period" {

variable "api_keys" {
description = "List of api keys created and assigned to the usage plan"
type = list(any)
default = []
# It is a list of objects with the keyname and enabled flag. ex: [ { "key_name" : "key1", "enabled" : true }]
type = map(
object({
key_name = string
enabled = bool
})
)
default = {}
}

0 comments on commit 9aea20f

Please sign in to comment.