Terraform-provider-aws: API Gateway Stages - Add support for Cloudwatch settings

Created on 4 Jul 2019  路  4Comments  路  Source: hashicorp/terraform-provider-aws

Currently, the only monitoring settings that can be managed when creating a stage are Access logging and X-Ray tracing. Would be great to be able to 'Enable Cloudwatch Logs' and 'Enable Detailed Cloudwatch Metrics'

image

enhancement needs-triage serviccloudwatch serviccloudwatchlogs

Most helpful comment

I also need the ability to enable "Enable Detailed CloudWatch Metrics" easily on an API Gateway stage.

All 4 comments

Not sure if the state of this will change, however I have been working on workaround for this in the meantime. Here is what I have found.

If your using cloudwatch settings (new) - There is the options of "Share your data", "View cross-account cross-region", and "Share your organization account list". You could use the aws console to enable these options ( master org account or sub accounts ). It does seem that these options are not directly available within the aws_cloudwatch* resources in terraform. What these are actually doing is mostly creating Roles and attaching appropriate policies.

"Share your data" - run this within one of your sub accounts:
data "aws_iam_policy_document" "CloudWatch-CrossAccountSharingRole-assume-policy" {
statement {
actions = [
"sts:AssumeRole"
]
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::MASTER ACCOUNT #:root"
]
}
}
provider = aws
}

data "aws_iam_policy" "CloudWatchReadOnlyAccess" {
arn = "arn:aws:iam::aws:policy/CloudWatchReadOnlyAccess"
provider = aws
}

data "aws_iam_policy" "CloudWatchAutomaticDashboardsAccess" {
arn = "arn:aws:iam::aws:policy/CloudWatchAutomaticDashboardsAccess"
provider = aws
}

resource "aws_iam_role" "CloudWatch-CrossAccountSharingRole" {
name = "CloudWatch-CrossAccountSharingRole"
assume_role_policy = data.aws_iam_policy_document.CloudWatch-CrossAccountSharingRole-assume-policy.json
provider = aws
}

resource "aws_iam_role_policy_attachment" "CloudWatchReadOnlyAccess-to-CloudWatch-CrossAccountSharingRole" {
role = aws_iam_role.CloudWatch-CrossAccountSharingRole.name
policy_arn = data.aws_iam_policy.CloudWatchReadOnlyAccess.arn
provider = aws
}

resource "aws_iam_role_policy_attachment" "CloudWatchAutomaticDashboardsAccess-to-CloudWatch-CrossAccountSharingRole" {
role = aws_iam_role.CloudWatch-CrossAccountSharingRole.name
policy_arn = data.aws_iam_policy.CloudWatchAutomaticDashboardsAccess.arn
provider = aws
}

Then for "View cross-account cross-region", and "Share your organization account list" - you would execute this code within your aws master account.

data "aws_iam_policy_document" "CloudWatch-CrossAccountSharing-ListAccountsRole-trust-relationship" {
statement {
actions = [
"sts:AssumeRole"
]
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::acct#1:root",
"arn:aws:iam::acct#2:root",
"arn:aws:iam::acct#3:root",
"arn:aws:iam::acct#4:root"
]
}
}
provider = aws
}

resource "aws_iam_role" "CloudWatch-CrossAccountSharing-ListAccountsRole" {
name = "CloudWatch-CrossAccountSharing-ListAccountsRole"
assume_role_policy = data.aws_iam_policy_document.CloudWatch-CrossAccountSharing-ListAccountsRole-trust-relationship.json
provider = aws
}

data "aws_iam_policy_document" "CloudWatch-CrossAccountSharing-ListAccounts-Policy" {
statement {
actions = [
"organizations:ListAccounts",
"organizations:ListAccountsForParent"
]
resources = [
"*"
]
}
provider = aws
}

resource "aws_iam_role_policy" "CloudWatch-CrossAccountSharing-ListAccounts-Policy" {
name = "CloudWatch-CrossAccountSharing-ListAccounts-Policy"
role = aws_iam_role.CloudWatch-CrossAccountSharing-ListAccountsRole.id
policy = data.aws_iam_policy_document.CloudWatch-CrossAccountSharing-ListAccounts-Policy.json
provider = aws
}

resource "aws_iam_service_linked_role" "AWSServiceRoleForCloudWatchCrossAccount" {
aws_service_name = "cloudwatch-crossaccount.amazonaws.com"
provider = aws
}

If you terraform these resources and then check back into cloudwatch settings ( master account or sub account ) you will see that the settings are now marked as ENABLED.

Hope this helps as a temporary work around

I also need the ability to enable "Enable Detailed CloudWatch Metrics" easily on an API Gateway stage.

Those setting are managed by aws_api_gateway_method_settings.

Example:

resource "aws_api_gateway_method_settings" "default" {
  rest_api_id = "${aws_api_gateway_rest_api.default.id}"
  stage_name  = "${var.stage_name}"
  method_path = "*/*"

  settings {
    metrics_enabled     = true
    logging_level       = "INFO"
    data_trace_enabled  = true
  }
}

I guess aws_api_gateway_method_settings resource type name is a little bit confusing. Method and Stage are separate resources in API Gateway entities model. Despite Stage settings may imply to Methods, they belong to Stage. This is not reflected in the resource type name.

Proposals

  1. Rename to aws_api_gateway_stage_method_settings (correlates with API action name and parameter)
  2. Migrate method settings to aws_api_gateway_stage.method_setting block
resource aws_api_gateway_stage example {
  rest_api_id   = aws_api_gateway_rest_api.example.id
  deployment_id = aws_api_gateway_deployment.example.id
  stage_name    = "v1"

  method_settings {
    method_path        = "/x"
    metrics_enabled    = true
    data_trace_enabled = true
    logging_level      = "INFO"
  }

  method_settings {
    method_path        = "/y"
    metrics_enabled    = false
    data_trace_enabled = false
    logging_level      = "ERROR"
  }
}

Does it make sense?

Was this page helpful?
0 / 5 - 0 ratings