Initial Terraform ALB Loggin Module (#10010)

This commit is contained in:
Robert Fairburn 2023-02-22 10:07:12 -06:00 committed by GitHub
parent 37c90502a6
commit de888d3cb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 334 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# ALB Logging Addon
This addon creates alb logging bucket(s) in s3 and optionally an athena database for those logs.
# Example Configuration
This assumes your fleet module is `main` and is configured with it's default documentation.
See https://github.com/fleetdm/fleet/blob/main/terraform/example/main.tf for details.
```
module "main" {
source = "github.com/fleetdm/fleet//terraform?ref=main"
certificate_arn = module.acm.acm_certificate_arn
vpc = {
name = random_pet.main.id
}
fleet_config = {
extra_environment_variables = module.firehose-logging.fleet_extra_environment_variables
extra_iam_policies = module.firehose-logging.fleet_extra_iam_policies
}
alb_config = {
access_logs = {
bucket = module.logging_alb.log_s3_bucket_id
prefix = "fleet"
enabled = true
}
}
}
module "logging_alb" {
source = "github.com/fleetdm/fleet//terraform/addons/logging-alb?ref=main"
prefix = "fleet"
enable_athena = true
}
```
# Additional Information
Once this terraform is applied, the Athena table will need to be created. See https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.html for help with creating the table.
For this implementation, the S3 pattern for the `CREATE TABLE` query should look like this:
```
s3://your-alb-logs-bucket/<PREFIX>/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/
```

View file

@ -0,0 +1 @@
header-from: .header.md

View file

@ -0,0 +1,91 @@
# ALB Logging Addon
This addon creates alb logging bucket(s) in s3 and optionally an athena database for those logs.
# Example Configuration
This assumes your fleet module is `main` and is configured with it's default documentation.
See https://github.com/fleetdm/fleet/blob/main/terraform/example/main.tf for details.
```
module "main" {
source = "github.com/fleetdm/fleet//terraform?ref=main"
certificate_arn = module.acm.acm_certificate_arn
vpc = {
name = random_pet.main.id
}
fleet_config = {
extra_environment_variables = module.firehose-logging.fleet_extra_environment_variables
extra_iam_policies = module.firehose-logging.fleet_extra_iam_policies
}
alb_config = {
access_logs = {
bucket = module.logging_alb.log_s3_bucket_id
prefix = "fleet"
enabled = true
}
}
}
module "logging_alb" {
source = "github.com/fleetdm/fleet//terraform/addons/logging-alb?ref=main"
prefix = "fleet"
enable_athena = true
}
```
# Additional Information
Once this terraform is applied, the Athena table will need to be created. See https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.html for help with creating the table.
For this implementation, the S3 pattern for the `CREATE TABLE` query should look like this:
```
s3://your-alb-logs-bucket/<PREFIX>/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/
```
## Requirements
No requirements.
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_athena-s3-bucket"></a> [athena-s3-bucket](#module\_athena-s3-bucket) | terraform-aws-modules/s3-bucket/aws | 3.6.0 |
| <a name="module_s3_bucket_for_logs"></a> [s3\_bucket\_for\_logs](#module\_s3\_bucket\_for\_logs) | terraform-aws-modules/s3-bucket/aws | 3.6.0 |
## Resources
| Name | Type |
|------|------|
| [aws_athena_database.logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/athena_database) | resource |
| [aws_athena_workgroup.logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/athena_workgroup) | resource |
| [aws_kms_alias.logs_alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_key.logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.kms](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_enable_athena"></a> [enable\_athena](#input\_enable\_athena) | n/a | `bool` | `true` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | n/a | `string` | `"fleet"` | no |
| <a name="input_s3_expiration_days"></a> [s3\_expiration\_days](#input\_s3\_expiration\_days) | n/a | `number` | `90` | no |
| <a name="input_s3_newer_noncurrent_versions"></a> [s3\_newer\_noncurrent\_versions](#input\_s3\_newer\_noncurrent\_versions) | n/a | `number` | `5` | no |
| <a name="input_s3_noncurrent_version_expiration_days"></a> [s3\_noncurrent\_version\_expiration\_days](#input\_s3\_noncurrent\_version\_expiration\_days) | n/a | `number` | `30` | no |
| <a name="input_s3_transition_days"></a> [s3\_transition\_days](#input\_s3\_transition\_days) | n/a | `number` | `30` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_log_s3_bucket_id"></a> [log\_s3\_bucket\_id](#output\_log\_s3\_bucket\_id) | n/a |

View file

@ -0,0 +1,162 @@
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_iam_policy_document" "kms" {
statement {
actions = ["kms:*"]
principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
resources = ["*"]
}
statement {
actions = [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*",
]
resources = ["*"]
principals {
type = "Service"
identifiers = ["logs.${data.aws_region.current.name}.amazonaws.com"]
}
}
}
resource "aws_kms_key" "logs" {
policy = data.aws_iam_policy_document.kms.json
enable_key_rotation = true
}
resource "aws_kms_alias" "logs_alias" {
name_prefix = "alias/${var.prefix}-logs"
target_key_id = aws_kms_key.logs.id
}
module "s3_bucket_for_logs" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "3.6.0"
bucket = "${var.prefix}-alb-logs"
acl = "log-delivery-write"
# Allow deletion of non-empty bucket
force_destroy = true
attach_elb_log_delivery_policy = true # Required for ALB logs
attach_lb_log_delivery_policy = true # Required for ALB/NLB logs
attach_deny_insecure_transport_policy = true
attach_require_latest_tls_policy = true
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
server_side_encryption_configuration = {
rule = {
apply_server_side_encryption_by_default = {
kms_master_key_id = aws_kms_key.logs.arn
sse_algorithm = "aws:kms"
}
}
}
lifecycle_rule = [
{
id = "log"
enabled = true
transition = [
{
days = var.s3_transition_days
storage_class = "ONEZONE_IA"
}
]
expiration = {
days = var.s3_expiration_days
expired_object_delete_marker = true
}
noncurrent_version_expiration = {
newer_noncurrent_versions = var.s3_newer_noncurrent_versions
days = var.s3_noncurrent_version_expiration_days
}
}
]
}
resource "aws_athena_database" "logs" {
count = var.enable_athena == true ? 1 : 0
name = replace("${var.prefix}-alb-logs", "-", "_")
bucket = module.athena-s3-bucket[0].s3_bucket_id
}
module "athena-s3-bucket" {
count = var.enable_athena == true ? 1 : 0
source = "terraform-aws-modules/s3-bucket/aws"
version = "3.6.0"
bucket = "${var.prefix}-alb-logs-athena"
acl = "log-delivery-write"
# Allow deletion of non-empty bucket
force_destroy = true
attach_elb_log_delivery_policy = true # Required for ALB logs
attach_lb_log_delivery_policy = true # Required for ALB/NLB logs
attach_deny_insecure_transport_policy = true
attach_require_latest_tls_policy = true
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
server_side_encryption_configuration = {
rule = {
apply_server_side_encryption_by_default = {
kms_master_key_id = aws_kms_key.logs.arn
sse_algorithm = "aws:kms"
}
}
}
lifecycle_rule = [
{
id = "log"
enabled = true
transition = [
{
days = var.s3_transition_days
storage_class = "ONEZONE_IA"
}
]
expiration = {
days = var.s3_expiration_days
expired_object_delete_marker = true
}
noncurrent_version_expiration = {
newer_noncurrent_versions = var.s3_newer_noncurrent_versions
days = var.s3_noncurrent_version_expiration_days
}
}
]
}
resource "aws_athena_workgroup" "logs" {
count = var.enable_athena == true ? 1 : 0
name = "${var.prefix}-logs"
configuration {
enforce_workgroup_configuration = true
publish_cloudwatch_metrics_enabled = true
result_configuration {
output_location = "s3://${module.athena-s3-bucket[0].s3_bucket_id}/output/"
encryption_configuration {
encryption_option = "SSE_KMS"
kms_key_arn = aws_kms_key.logs.arn
}
}
}
}

View file

@ -0,0 +1,3 @@
output "log_s3_bucket_id" {
value = module.s3_bucket_for_logs.s3_bucket_id
}

View file

@ -0,0 +1,30 @@
variable "prefix" {
type = string
default = "fleet"
}
variable "enable_athena" {
type = bool
default = true
}
variable "s3_transition_days" {
type = number
default = 30
}
variable "s3_expiration_days" {
type = number
default = 90
}
variable "s3_newer_noncurrent_versions" {
type = number
default = 5
}
variable "s3_noncurrent_version_expiration_days" {
type = number
default = 30
}

View file

@ -35,6 +35,7 @@ module "alb" {
vpc_id = var.vpc_id
subnets = var.alb_config.subnets
security_groups = concat(var.alb_config.security_groups, [aws_security_group.alb.id])
access_logs = var.alb_config.access_logs
target_groups = [
{