Hi there!
I'm trying to disable caching for a method in API Gateway. When I add a method setting to disable caching for the method nothing seems to change in the AWS UI, the method continues to inherit stage default settings. If I set caching_enable to true for the method then the stage default settings are overriden and caching is enabled on the method.
Terraform v0.10.2
provider "aws" {
version = "~> 0.1"
access_key = "key"
secret_key = "secret"
region = "region"
}
resource "aws_api_gateway_rest_api" "api" {
name = "MyDemoAPI"
description = "This is my API for demonstration purposes"
}
resource "aws_api_gateway_deployment" "dev" {
depends_on = ["aws_api_gateway_integration.uncached_integration", "aws_api_gateway_integration.cached_integration"]
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
stage_name = "dev"
}
resource "aws_api_gateway_stage" "prod" {
stage_name = "prod"
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
deployment_id = "${aws_api_gateway_deployment.dev.id}"
cache_cluster_enabled = true
cache_cluster_size = "0.5"
}
resource "aws_api_gateway_resource" "uncached_resource" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
parent_id = "${aws_api_gateway_rest_api.api.root_resource_id}"
path_part = "uncached_testresource"
}
resource "aws_api_gateway_method" "uncached_method" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
resource_id = "${aws_api_gateway_resource.uncached_resource.id}"
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "uncached_integration" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
resource_id = "${aws_api_gateway_resource.uncached_resource.id}"
http_method = "${aws_api_gateway_method.uncached_method.http_method}"
type = "MOCK"
request_templates {
"application/xml" = <<EOF
{
"body" : $input.json('$')
}
EOF
}
}
resource "aws_api_gateway_method_settings" "uncached_settings" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
stage_name = "${aws_api_gateway_stage.prod.stage_name}"
method_path = "${aws_api_gateway_resource.uncached_resource.path_part}/${aws_api_gateway_method.uncached_method.http_method}"
settings {
caching_enabled = false
}
}
resource "aws_api_gateway_resource" "cached_resource" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
parent_id = "${aws_api_gateway_rest_api.api.root_resource_id}"
path_part = "cached_resource"
}
resource "aws_api_gateway_method" "cached_method" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
resource_id = "${aws_api_gateway_resource.cached_resource.id}"
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "cached_integration" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
resource_id = "${aws_api_gateway_resource.cached_resource.id}"
http_method = "${aws_api_gateway_method.cached_method.http_method}"
type = "MOCK"
request_templates {
"application/xml" = <<EOF
{
"body" : $input.json('$')
}
EOF
}
}
resource "aws_api_gateway_method_settings" "cached_settings" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
stage_name = "${aws_api_gateway_stage.prod.stage_name}"
method_path = "${aws_api_gateway_resource.cached_resource.path_part}/${aws_api_gateway_method.cached_method.http_method}"
settings {
caching_enabled = true
cache_ttl_in_seconds = "3600"
}
}
The uncached method should override the stage default cache settings and should not enable caching.
The uncached method inherits the stage default cache settings.
terraform applyWas anybody able to take a look into this?
I have encountered this issue as well. After digging up a little bit I believe the problem occurs when the aws_api_gateway_method_settings resource only contains values that match the default value for their types (e.g., false for a boolean or 0 for an integer).
For instance, if I try to change the settings of a method by declaring:
resource "aws_api_gateway_method_settings" "foo_method_settings" {
rest_api_id = "${aws_api_gateway_rest_api.api.id}"
stage_name = "${aws_api_gateway_stage.stage.stage_name}"
method_path = "foo/GET"
settings {
throttling_rate_limit = 0
}
}
then Terraform does not perform any update patch operation as 0 is the default value (from the point of view of Terraform) for the type of field throttling_rate_limit. But, if I change throttling_rate_limit = 0 to throttling_rate_limit = 1 then the settings for method foo are correctly overridden.
This is clearly a bug as the default value for throttling_rate_limit in AWS is 10000, not 0. So, an update patch operation must be requested if throttling_rate_limit is set to 0.
I believe the problem lies in the fact that resourceAwsApiGatewayMethodSettingsUpdate is used to both to create and update the method settings:
func resourceAwsApiGatewayMethodSettings() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGatewayMethodSettingsUpdate,
Read: resourceAwsApiGatewayMethodSettingsRead,
Update: resourceAwsApiGatewayMethodSettingsUpdate,
Delete: resourceAwsApiGatewayMethodSettingsDelete,
// ...
The update function checks whether there is a change in a given setting:
func resourceAwsApiGatewayMethodSettingsUpdate(d *schema.ResourceData, meta interface{}) error {
// ...
if d.HasChange("settings.0.throttling_rate_limit") {
ops = append(ops, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String(prefix + "throttling/rateLimit"),
Value: aws.String(fmt.Sprintf("%f", d.Get("settings.0.throttling_rate_limit").(float64))),
})
}
// ...
Although, I have not really tried, I believe d.HasChange("settings.0.throttling_rate_limit") will return false when throttling_rate_limit is set to 0 as the requested value matches the default value for the value type (float64).
I believe this can be easily solved by just using a real create method that simply passes to AWS whatever values the user has specified in the aws_api_gateway_method_settings resource. Does this sound reasonable?
Any update on this issue, or any workaround ?
Got several endpoints where caching is enable and can't disable it even if caching_enable is set to false in aws_api_gateway_method_settings
EDIT: workaround found !
Setting a aws_api_gateway_method_settings with a method_path: '*/*' and caching_enabled:false will refresh correctly others methods who have caching disabled.
Example :
aws_api_gateway_method_settings: {
['${PREFIX}']: {
rest_api_id: '\${aws_api_gateway_rest_api.${PREFIX}.id}',
stage_name: '\${aws_api_gateway_stage.${PREFIX}.stage_name}',
method_path: '*/*',
settings: {
metrics_enabled: true,
logging_level: 'INFO',
data_trace_enabled: true,
caching_enabled: false,
throttling_burst_limit: 5000,
throttling_rate_limit: 10000,
}
}
}
Method settigns is completely broken. (Terraform v0.11.14, provider.aws v2.15.0)
These are my definitions.
resource "aws_api_gateway_method_settings" "default" {
rest_api_id = "${aws_api_gateway_rest_api.service.id}"
stage_name = "${aws_api_gateway_stage.v2.stage_name}"
method_path = "*/*"
settings {
caching_enabled = true
require_authorization_for_cache_control = false
cache_ttl_in_seconds = 3600
logging_level = "OFF"
}
depends_on = ["aws_api_gateway_stage.v2"]
}
resource "aws_api_gateway_method_settings" "get_source_find" {
rest_api_id = "${aws_api_gateway_rest_api.service.id}"
stage_name = "${aws_api_gateway_stage.v2.stage_name}"
method_path = "${substr(aws_api_gateway_resource.source_find.path,1,-1)}/${aws_api_gateway_method.get_source_find.http_method}"
settings {
caching_enabled = false
}
depends_on = ["aws_api_gateway_stage.v2", "aws_api_gateway_method_settings.default"]
}
resource "aws_api_gateway_method_settings" "get_source_config_find" {
rest_api_id = "${aws_api_gateway_rest_api.service.id}"
stage_name = "${aws_api_gateway_stage.v2.stage_name}"
method_path = "${substr(aws_api_gateway_resource.source_config_find.path,1,-1)}/${aws_api_gateway_method.get_source_config_find.http_method}"
settings {
caching_enabled = false
}
depends_on = ["aws_api_gateway_stage.v2", "aws_api_gateway_method_settings.default"]
}
And these are the logs.
+ module.source_service.aws_api_gateway_method_settings.default
id: <computed>
method_path: "*/*"
rest_api_id: "EREASED"
settings.#: "1"
settings.0.cache_ttl_in_seconds: "3600"
settings.0.caching_enabled: "true"
settings.0.logging_level: "OFF"
settings.0.require_authorization_for_cache_control: "false"
stage_name: "v2"
+ module.source_service.aws_api_gateway_method_settings.get_source_config_find
id: <computed>
method_path: "${substr(aws_api_gateway_resource.source_config_find.path,1,-1)}/${aws_api_gateway_method.get_source_config_find.http_method}"
rest_api_id: "EREASED"
settings.#: "1"
settings.0.caching_enabled: "false"
stage_name: "v2"
+ module.source_service.aws_api_gateway_method_settings.get_source_find
id: <computed>
method_path: "${substr(aws_api_gateway_resource.source_find.path,1,-1)}/${aws_api_gateway_method.get_source_find.http_method}"
rest_api_id: "EREASED"
settings.#: "1"
settings.0.caching_enabled: "false"
stage_name: "v2"
It is clear that though require_authorization_for_cache_control is set to false it's not in the patch operations.
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: 2019/06/19 09:07:37 [DEBUG] Updating API Gateway Stage: {
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: /: [{
settings.#: "" => "1"
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Op: "replace",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Path: "/*/*/logging/loglevel",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Value: "OFF"
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: },{
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Op: "replace",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Path: "/*/*/caching/enabled",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Value: "true"
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: },{
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Op: "replace",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Path: "/*/*/caching/ttlInSeconds",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: Value: "3600"
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: }],
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: RestApiId: "EREASED",
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: StageName: "v2"
2019-06-19T09:07:37.767+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: }
settings.0.cache_ttl_in_seconds: "" => "3600"
Disabling cache is also not in the patch operations for the other methods.
2019-06-19T09:07:38.342+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: 2019/06/19 09:07:38 [DEBUG] Updating API Gateway Stage: {
method_path: "" => "source/find/GET"
2019-06-19T09:07:38.343+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: /: [],
2019-06-19T09:07:38.343+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: RestApiId: "EREASED",
2019-06-19T09:07:38.343+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: StageName: "v2"
2019-06-19T09:07:38.343+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: }
2019-06-19T09:07:39.029+0200 [DEBUG] plugin.terraform-provider-aws_v2.15.0_x4: 2019/06/19 09:07:39 [WARN] API Gateway Method Settings for "source/find/GET" not found, removing
Using aws cli to describe the stage makes it also clear that it does not work.
Only / method setting is applied but the requireAuthorizationForCacheControl was ignored.
{
"deploymentId": "EREASED",
"stageName": "v2",
"cacheClusterEnabled": true,
"cacheClusterSize": "1.6",
"cacheClusterStatus": "AVAILABLE",
"methodSettings": {
"*/*": {
"metricsEnabled": false,
"loggingLevel": "OFF",
"dataTraceEnabled": false,
"throttlingBurstLimit": 5000,
"throttlingRateLimit": 10000.0,
"cachingEnabled": true,
"cacheTtlInSeconds": 3600,
"cacheDataEncrypted": false,
"requireAuthorizationForCacheControl": true,
"unauthorizedCacheControlHeaderStrategy": "SUCCEED_WITH_RESPONSE_HEADER"
}
},
"createdDate": 1560927844,
"lastUpdatedDate": 1560928831
}
What you can do as a workaround if you have aws cli where you run terraform is to run aws cli commands with a local-exec provisioner either in a null resource or at the method_settings resource.
provisioner "local-exec" {
command = "aws apigateway update-stage --rest-api-id ${aws_api_gateway_rest_api.service.id} --stage-name ${aws_api_gateway_stage.v2.stage_name} --patch-operations op=replace,path=${aws_api_gateway_resource.source_config_find.path}/GET/caching/enabled,value=false"
}
provisioner "local-exec" {
command = "aws apigateway update-stage --rest-api-id ${aws_api_gateway_rest_api.service.id} --stage-name ${aws_api_gateway_stage.v2.stage_name} --patch-operations op=replace,path=${aws_api_gateway_resource.source_find.path}/GET/caching/enabled,value=false"
}
provisioner "local-exec" {
command = "aws apigateway update-stage --rest-api-id ${aws_api_gateway_rest_api.service.id} --stage-name ${aws_api_gateway_stage.v2.stage_name} --patch-operations op=replace,path=/*/*/caching/requireAuthorizationForCacheControl,value=false"
}
Came across the same problem as zoltan-toth-mw.
unfortunately "Require authorization" setting is set to true by default.
the workaround I found is: