hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.61k stars 9k forks source link

API Gateway Stages - Add support for Cloudwatch settings #9238

Open GeorgeShort opened 5 years ago

GeorgeShort commented 5 years ago

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

rturnbull1977 commented 4 years ago

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

cloudmaniac commented 4 years ago

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

mkubenka commented 4 years ago

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
  }
}
Tensho commented 3 years ago

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?