|
| 1 | + |
| 2 | +# AWS API Gateway Terraform Module |
| 3 | + |
| 4 | +# [terraform-aws-arc-api-gateway](https://github.com/sourcefuse/terraform-aws-arc-api-gateway) |
| 5 | + |
| 6 | +<a href="https://github.com/sourcefuse/terraform-aws-arc-api-gateway/releases/latest"><img src="https://img.shields.io/github/release/sourcefuse/terraform-aws-arc-api-gateway.svg?style=for-the-badge" alt="Latest Release"/></a> <a href="https://github.com/sourcefuse/terraform-aws-arc-api-gateway/commits"><img src="https://img.shields.io/github/last-commit/sourcefuse/terraform-aws-arc-api-gateway.svg?style=for-the-badge" alt="Last Updated"/></a>   |
| 7 | + |
| 8 | +[](https://sonarcloud.io/summary/new_code?id=sourcefuse_terraform-aws-arc-api-gateway) |
| 9 | + |
| 10 | + |
| 11 | +## Overview |
| 12 | + |
| 13 | +The API Gateway Terraform module provides an easy way to create and manage REST APIs on AWS. It supports defining resources, methods (GET, POST, etc.), and integrations with Lambda functions or other AWS services. The module also supports adding usage plans and API keys, enabling you to manage access, throttle requests, and monitor API usage. This helps ensure secure, scalable, and well-governed API deployments. |
| 14 | + |
| 15 | +### Prerequisites |
| 16 | +Before using this module, ensure you have the following: |
| 17 | + |
| 18 | +- AWS credentials configured. |
| 19 | +- Terraform installed. |
| 20 | +- A working knowledge of Terraform. |
| 21 | + |
| 22 | +## Getting Started |
| 23 | + |
| 24 | +1. **Define the Module** |
| 25 | + |
| 26 | +Initially, it's essential to define a Terraform module, which is organized as a distinct directory encompassing Terraform configuration files. Within this module directory, input variables and output values must be defined in the variables.tf and outputs.tf files, respectively. The following illustrates an example directory structure: |
| 27 | + |
| 28 | + |
| 29 | + |
| 30 | +```plaintext |
| 31 | +api-gateway/ |
| 32 | +|-- main.tf |
| 33 | +|-- variables.tf |
| 34 | +|-- outputs.tf |
| 35 | +``` |
| 36 | + |
| 37 | + |
| 38 | +2. **Define Input Variables** |
| 39 | + |
| 40 | +Inside the `variables.tf` or in `*.tfvars` file, you should define values for the variables that the module requires. |
| 41 | + |
| 42 | +3. **Use the Module in Your Main Configuration** |
| 43 | +In your main Terraform configuration file (e.g., main.tf), you can use the module. Specify the source of the module, and version, For Example |
| 44 | + |
| 45 | +```hcl |
| 46 | +module "api_gateway" { |
| 47 | + source = "sourcefuse/arc-api-gateway/aws" |
| 48 | + version = "0.0.1" |
| 49 | +
|
| 50 | + name = "arc-app" |
| 51 | + stage_name = "dev" |
| 52 | + endpoint_type = "REGIONAL" |
| 53 | + open_api_json = file("${path.module}/openapi.json") |
| 54 | +
|
| 55 | + enable_cloudwatch_logs = true |
| 56 | +
|
| 57 | + # Custom domain (optional) |
| 58 | + api_gateway_domain = { |
| 59 | + create = true |
| 60 | + domain = "arc-api.${local.domain}" |
| 61 | + certificate_arn = data.aws_acm_certificate.this.arn |
| 62 | + route53_root_domain = local.domain |
| 63 | + } |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +4. **Output Values** |
| 68 | + |
| 69 | +Inside the `outputs.tf` file of the module, you can define output values that can be referenced in the main configuration. For example: |
| 70 | + |
| 71 | +```hcl |
| 72 | +output "id" { |
| 73 | + description = "The ID of the API Gateway REST API" |
| 74 | + value = module.api_gateway.id |
| 75 | +} |
| 76 | +
|
| 77 | +output "arn" { |
| 78 | + description = "The ARN of the API Gateway REST API" |
| 79 | + value = module.api_gateway.arn |
| 80 | +} |
| 81 | +
|
| 82 | +output "execution_arn" { |
| 83 | + description = "The execution ARN of the API Gateway (useful for Lambda permissions)" |
| 84 | + value = module.api_gateway.execution_arn |
| 85 | +} |
| 86 | +
|
| 87 | +``` |
| 88 | + |
| 89 | +5. **.tfvars** |
| 90 | + |
| 91 | +Inside the `.tfvars` file of the module, you can provide desired values that can be referenced in the main configuration. |
| 92 | + |
| 93 | + |
| 94 | +## First Time Usage |
| 95 | +***uncomment the backend block in [main.tf](./examples/endpoint//main.tf)*** |
| 96 | +```shell |
| 97 | +terraform init -backend-config=config.dev.hcl |
| 98 | +``` |
| 99 | +***If testing locally, `terraform init` should be fine*** |
| 100 | + |
| 101 | +Create a `dev` workspace |
| 102 | +```shell |
| 103 | +terraform workspace new dev |
| 104 | +``` |
| 105 | + |
| 106 | +Plan Terraform |
| 107 | +```shell |
| 108 | +terraform plan -var-file dev.tfvars |
| 109 | +``` |
| 110 | + |
| 111 | +Apply Terraform |
| 112 | +```shell |
| 113 | +terraform apply -var-file dev.tfvars |
| 114 | +``` |
| 115 | + |
| 116 | +## Production Setup |
| 117 | +```shell |
| 118 | +terraform init -backend-config=config.prod.hcl |
| 119 | +``` |
| 120 | + |
| 121 | +Create a `prod` workspace |
| 122 | +```shell |
| 123 | +terraform workspace new prod |
| 124 | +``` |
| 125 | + |
| 126 | +Plan Terraform |
| 127 | +```shell |
| 128 | +terraform plan -var-file prod.tfvars |
| 129 | +``` |
| 130 | + |
| 131 | +Apply Terraform |
| 132 | +```shell |
| 133 | +terraform apply -var-file prod.tfvars |
| 134 | +``` |
| 135 | +<!-- BEGIN_TF_DOCS --> |
| 136 | +## Requirements |
| 137 | + |
| 138 | +| Name | Version | |
| 139 | +|------|---------| |
| 140 | +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3, < 2.0.0 | |
| 141 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0, < 6.0 | |
| 142 | + |
| 143 | +## Providers |
| 144 | + |
| 145 | +| Name | Version | |
| 146 | +|------|---------| |
| 147 | +| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.100.0 | |
| 148 | +| <a name="provider_terraform"></a> [terraform](#provider\_terraform) | n/a | |
| 149 | + |
| 150 | +## Modules |
| 151 | + |
| 152 | +No modules. |
| 153 | + |
| 154 | +## Resources |
| 155 | + |
| 156 | +| Name | Type | |
| 157 | +|------|------| |
| 158 | +| [aws_api_gateway_account.api_gateway_account](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_account) | resource | |
| 159 | +| [aws_api_gateway_api_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_api_key) | resource | |
| 160 | +| [aws_api_gateway_base_path_mapping.base_path_mapping](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_base_path_mapping) | resource | |
| 161 | +| [aws_api_gateway_deployment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_deployment) | resource | |
| 162 | +| [aws_api_gateway_domain_name.custom_domain](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_domain_name) | resource | |
| 163 | +| [aws_api_gateway_rest_api.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_rest_api) | resource | |
| 164 | +| [aws_api_gateway_stage.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_stage) | resource | |
| 165 | +| [aws_api_gateway_usage_plan.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_usage_plan) | resource | |
| 166 | +| [aws_api_gateway_usage_plan_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_usage_plan_key) | resource | |
| 167 | +| [aws_iam_role.api_gateway_account_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | |
| 168 | +| [aws_iam_role_policy.api_gateway_cloudwatch_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | |
| 169 | +| [aws_route53_record.api_gateway_alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | |
| 170 | +| [terraform_data.replacement](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | |
| 171 | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | |
| 172 | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | |
| 173 | +| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | |
| 174 | + |
| 175 | +## Inputs |
| 176 | + |
| 177 | +| Name | Description | Type | Default | Required | |
| 178 | +|------|-------------|------|---------|:--------:| |
| 179 | +| <a name="input_access_log_format"></a> [access\_log\_format](#input\_access\_log\_format) | Acess log format for API Gateway | `string` | `null` | no | |
| 180 | +| <a name="input_api_gateway_domain"></a> [api\_gateway\_domain](#input\_api\_gateway\_domain) | Configuration for API Gateway custom domain and Route53 record | <pre>object({<br/> create = optional(bool, false)<br/> domain = string # eg. "api.example.com"<br/> route53_root_domain = string # eg. "example.com"<br/> certificate_arn = string # ACM cert ARN<br/> })</pre> | n/a | yes | |
| 181 | +| <a name="input_api_key_map"></a> [api\_key\_map](#input\_api\_key\_map) | Configuration for API Gateway API keys.<br/>Each API key entry represents a client or application that requires access<br/>to the API, and can be associated with one or more usage plans.<br/><br/>Fields:<br/>- name : The name of the API key (must be unique).<br/>- description : Optional description of the API key (e.g., which client it belongs to).<br/>- usage\_plan : List of usage plan names (from var.usage\_plan) this key should be associated with. This should match the names defined in var.usage\_plan | <pre>map(object({<br/> name = string<br/> description = string<br/> usage_plan = string // This should match the names defined in var.usage_plan<br/> }))</pre> | `{}` | no | |
| 182 | +| <a name="input_enable_cloudwatch_logs"></a> [enable\_cloudwatch\_logs](#input\_enable\_cloudwatch\_logs) | Whether to enable CloudWatch logs for API Gateway | `bool` | `true` | no | |
| 183 | +| <a name="input_endpoint_type"></a> [endpoint\_type](#input\_endpoint\_type) | API Gateway endpoint type. Valid values are 'EDGE', 'REGIONAL', or 'PRIVATE'. If not specified, defaults to 'REGIONAL'. | `string` | `"REGIONAL"` | no | |
| 184 | +| <a name="input_name"></a> [name](#input\_name) | Name of the API Gateway REST endpoint | `string` | n/a | yes | |
| 185 | +| <a name="input_open_api_json"></a> [open\_api\_json](#input\_open\_api\_json) | Open API JSON file | `string` | `null` | no | |
| 186 | +| <a name="input_security_policy"></a> [security\_policy](#input\_security\_policy) | The Transport Layer Security version for the custom domain. Valid values: TLS\_1\_0 or TLS\_1\_2 | `string` | `"TLS_1_2"` | no | |
| 187 | +| <a name="input_stage_name"></a> [stage\_name](#input\_stage\_name) | API Gateway stage name | `string` | n/a | yes | |
| 188 | +| <a name="input_tags"></a> [tags](#input\_tags) | Tags for the resources | `map(string)` | `{}` | no | |
| 189 | +| <a name="input_usage_plan"></a> [usage\_plan](#input\_usage\_plan) | Configuration for API Gateway usage plan | <pre>list(object({<br/> name = string<br/> description = optional(string, "API usage plan")<br/> quota_settings = object({<br/> limit = number<br/> offset = number<br/> period = string<br/> })<br/> throttle_settings = object({<br/> burst_limit = number<br/> rate_limit = number<br/> })<br/> }))</pre> | `[]` | no | |
| 190 | +| <a name="input_xray_tracing_enabled"></a> [xray\_tracing\_enabled](#input\_xray\_tracing\_enabled) | Enable X-Ray tracing for Lambda | `bool` | `true` | no | |
| 191 | + |
| 192 | +## Outputs |
| 193 | + |
| 194 | +| Name | Description | |
| 195 | +|------|-------------| |
| 196 | +| <a name="output_api_keys"></a> [api\_keys](#output\_api\_keys) | Map of API keys created (name => value) | |
| 197 | +| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the API Gateway REST API | |
| 198 | +| <a name="output_custom_domain"></a> [custom\_domain](#output\_custom\_domain) | The custom domain name for API Gateway (if created) | |
| 199 | +| <a name="output_custom_domain_regional_domain_name"></a> [custom\_domain\_regional\_domain\_name](#output\_custom\_domain\_regional\_domain\_name) | The regional domain name for the custom domain (if created) | |
| 200 | +| <a name="output_custom_domain_regional_zone_id"></a> [custom\_domain\_regional\_zone\_id](#output\_custom\_domain\_regional\_zone\_id) | The Route53 hosted zone ID for the custom domain | |
| 201 | +| <a name="output_deployment_id"></a> [deployment\_id](#output\_deployment\_id) | The ID of the current API Gateway deployment | |
| 202 | +| <a name="output_execution_arn"></a> [execution\_arn](#output\_execution\_arn) | The execution ARN of the API Gateway (useful for Lambda permissions) | |
| 203 | +| <a name="output_id"></a> [id](#output\_id) | The ID of the API Gateway REST API | |
| 204 | +| <a name="output_invoke_url"></a> [invoke\_url](#output\_invoke\_url) | Base invoke URL for the API Gateway stage | |
| 205 | +| <a name="output_stage_name"></a> [stage\_name](#output\_stage\_name) | The name of the API Gateway stage | |
| 206 | +| <a name="output_usage_plans"></a> [usage\_plans](#output\_usage\_plans) | Map of usage plans created | |
| 207 | +<!-- END_TF_DOCS --> |
| 208 | + |
| 209 | + |
| 210 | +## Versioning |
| 211 | +This project uses a `.version` file at the root of the repo which the pipeline reads from and does a git tag. |
| 212 | + |
| 213 | +When you intend to commit to `main`, you will need to increment this version. Once the project is merged, |
| 214 | +the pipeline will kick off and tag the latest git commit. |
| 215 | + |
| 216 | +## Development |
| 217 | + |
| 218 | +### Prerequisites |
| 219 | + |
| 220 | +- [terraform](https://learn.hashicorp.com/terraform/getting-started/install#installing-terraform) |
| 221 | +- [terraform-docs](https://github.com/segmentio/terraform-docs) |
| 222 | +- [pre-commit](https://pre-commit.com/#install) |
| 223 | +- [golang](https://golang.org/doc/install#install) |
| 224 | +- [golint](https://github.com/golang/lint#installation) |
| 225 | + |
| 226 | +### Configurations |
| 227 | + |
| 228 | +- Configure pre-commit hooks |
| 229 | + ```sh |
| 230 | + pre-commit install |
| 231 | + ``` |
| 232 | + |
| 233 | +### Versioning |
| 234 | + |
| 235 | +while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch |
| 236 | + |
| 237 | +For Example |
| 238 | + |
| 239 | +```sh |
| 240 | +git commit -m "your commit message #major" |
| 241 | +``` |
| 242 | +By specifying this , it will bump the version and if you don't specify this in your commit message then by default it will consider patch and will bump that accordingly |
| 243 | + |
| 244 | +### Tests |
| 245 | +- Tests are available in `test` directory |
| 246 | +- Configure the dependencies |
| 247 | + ```sh |
| 248 | + cd test/ |
| 249 | + go mod init github.com/sourcefuse/terraform-aws-refarch-<module_name> |
| 250 | + go get github.com/gruntwork-io/terratest/modules/terraform |
| 251 | + ``` |
| 252 | +- Now execute the test |
| 253 | + ```sh |
| 254 | + go test -timeout 30m |
| 255 | + ``` |
| 256 | + |
| 257 | +## Authors |
| 258 | + |
| 259 | +This project is authored by: |
| 260 | +- SourceFuse ARC Team |
0 commit comments