diff --git a/README.md b/README.md index 04be024..03e8863 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ This module consists of the following submodules: -- [prometheus](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/prometheus) -- [thanos](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/thanos) -- [loki](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/loki) -- [tempo](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/tempo) -- [grafana](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/grafana) -- [mimir](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/mimir) +- [Prometheus](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/prometheus) +- [Mimir](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/mimir) +- [Thanos](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/thanos) +- [Loki](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/loki) +- [Tempo](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/tempo) +- [Grafana](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/grafana) - [AWS Managed Service for Prometheus](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/amp) - [AWS Managed Grafana](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/amg) - [AWS Distro for OpenTelemetry (ADOT) Operator](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/adot) +- [CloudWatch](https://github.com/nlamirault/terraform-aws-observability/tree/master/modules/cloudwatch) See more details in each module's README. diff --git a/modules/cloudwatch/README.md b/modules/cloudwatch/README.md new file mode 100644 index 0000000..951fb2c --- /dev/null +++ b/modules/cloudwatch/README.md @@ -0,0 +1,53 @@ +# Observability / Cloudwatch + +Terraform module which configure Grafana Cloudwatch resources on Amazon AWS + +## Documentation + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0.0 | +| [aws](#requirement\_aws) | >= 4.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.0.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [agent](#module\_agent) | terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc | 5.5.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_cloudwatch_log_group.container_insights](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_kms_alias.cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_eks_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster) | data source | +| [aws_iam_policy.cloudwatch_agent_server](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | n/a | yes | +| [deletion\_window\_in\_days](#input\_deletion\_window\_in\_days) | Duration in days after which the key is deleted after destruction of the resource, must be between 7 and 30 days | `number` | `30` | no | +| [enable\_kms](#input\_enable\_kms) | Enable custom KMS key | `bool` | n/a | yes | +| [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | Number of days to retain log events | `number` | `90` | no | +| [namespace](#input\_namespace) | The Kubernetes namespace | `string` | n/a | yes | +| [service\_account](#input\_service\_account) | The Kubernetes service account | `string` | n/a | yes | +| [tags](#input\_tags) | Tags for Cloudwatch | `map(string)` |
{
"Made-By": "Terraform"
}
| no | + +## Outputs + +No outputs. + diff --git a/modules/cloudwatch/agent.tf b/modules/cloudwatch/agent.tf new file mode 100644 index 0000000..2f95814 --- /dev/null +++ b/modules/cloudwatch/agent.tf @@ -0,0 +1,32 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module "agent" { + source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc" + version = "5.5.0" + + create_role = true + role_description = "Cloudwatch Agent" + role_name = local.role_name + provider_url = data.aws_eks_cluster.this.identity[0].oidc[0].issuer + role_policy_arns = [ + data.aws_iam_policy.cloudwatch_agent_server.arn + ] + oidc_fully_qualified_subjects = ["system:serviceaccount:${var.namespace}:${var.service_account}"] + + tags = merge( + { "Name" = local.role_name }, + var.tags + ) +} diff --git a/modules/cloudwatch/data.tf b/modules/cloudwatch/data.tf new file mode 100644 index 0000000..8d6bf41 --- /dev/null +++ b/modules/cloudwatch/data.tf @@ -0,0 +1,21 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +data "aws_eks_cluster" "this" { + name = var.cluster_name +} + +data "aws_iam_policy" "cloudwatch_agent_server" { + arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" +} diff --git a/modules/cloudwatch/locals.tf b/modules/cloudwatch/locals.tf new file mode 100644 index 0000000..a020898 --- /dev/null +++ b/modules/cloudwatch/locals.tf @@ -0,0 +1,24 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +locals { + role_name = "cloudwatch-agent" + + container_insights_groups = [ + "application", + "dataplane", + "host", + "performance" + ] +} diff --git a/modules/cloudwatch/log.tf b/modules/cloudwatch/log.tf new file mode 100644 index 0000000..81204d7 --- /dev/null +++ b/modules/cloudwatch/log.tf @@ -0,0 +1,33 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resource "aws_cloudwatch_log_group" "cluster" { + name = format("/aws/eks/%s/cluster", data.aws_eks_cluster.id) + retention_in_days = var.log_retention_in_days + + kms_key_id = var.enable_kms ? aws_kms_key.cloudwatch[0].arn : null + + tags = var.tags +} + +resource "aws_cloudwatch_log_group" "container_insights" { + for_each = local.container_insights_groups + + name = format("/aws/containerinsights/%s/%s", data.aws_eks_cluster.id, each.key) + retention_in_days = var.log_retention_in_days + + kms_key_id = var.enable_kms ? aws_kms_key.cloudwatch[0].arn : null + + tags = var.tags +} diff --git a/modules/cloudwatch/main.tf b/modules/cloudwatch/main.tf new file mode 100644 index 0000000..dd601ae --- /dev/null +++ b/modules/cloudwatch/main.tf @@ -0,0 +1,24 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0.0" + } + } +} diff --git a/modules/cloudwatch/outputs.tf b/modules/cloudwatch/outputs.tf new file mode 100644 index 0000000..e65c150 --- /dev/null +++ b/modules/cloudwatch/outputs.tf @@ -0,0 +1,13 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/modules/cloudwatch/variables.tf b/modules/cloudwatch/variables.tf new file mode 100644 index 0000000..9c1e231 --- /dev/null +++ b/modules/cloudwatch/variables.tf @@ -0,0 +1,59 @@ +# Copyright (C) Nicolas Lamirault +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +############################################################################# +# Cloudwatch + +variable "cluster_name" { + type = string + description = "Name of the EKS cluster" +} + +variable "log_retention_in_days" { + description = "Number of days to retain log events" + type = number + default = 90 +} + +variable "namespace" { + type = string + description = "The Kubernetes namespace" +} + +variable "service_account" { + type = string + description = "The Kubernetes service account" +} + +variable "tags" { + type = map(string) + description = "Tags for Cloudwatch" + default = { + Made-By = "Terraform" + } +} + +############################################################################# +# KMS + +variable "enable_kms" { + type = bool + description = "Enable custom KMS key" +} + +variable "deletion_window_in_days" { + type = number + description = "Duration in days after which the key is deleted after destruction of the resource, must be between 7 and 30 days" + default = 30 +}