Skip to content

Commit 29aeb81

Browse files
authored
Merge pull request #16 from rhythmictech/v2
Updates for v2 release
2 parents 6866fbf + 0116ac0 commit 29aeb81

File tree

8 files changed

+140
-89
lines changed

8 files changed

+140
-89
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ override.tf.json
2727

2828
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
2929
# example: *tfplan*
30+
31+
.terraform.lock.hcl

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
exclude: ".terraform"
33
repos:
44
- repo: https://github.com/antonbabenko/pre-commit-terraform
5-
rev: v1.88.0
5+
rev: v1.105.0
66
hooks:
77
- id: terraform_docs
88
always_run: true

.terraform.lock.hcl

Lines changed: 0 additions & 48 deletions
This file was deleted.

.tflint.hcl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
config {
2-
module = true
32
}
43

54
plugin "aws" {
65
enabled = true
7-
version = "0.12.0"
6+
version = "0.45.0"
87
source = "github.com/terraform-linters/tflint-ruleset-aws"
98
}
109

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,21 @@ This module makes use of the AWS CLI to optionally create an Athena table.
2424

2525
If you would rather you can follow the instructions Amazon provides [here](https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.html) to set this up yourself.
2626

27-
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
27+
<!-- BEGIN_TF_DOCS -->
2828
## Requirements
2929

3030
| Name | Version |
3131
|------|---------|
32-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.4 |
33-
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.8 |
32+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5 |
33+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0 |
3434
| <a name="requirement_null"></a> [null](#requirement\_null) | >= 3 |
3535

3636
## Providers
3737

3838
| Name | Version |
3939
|------|---------|
40-
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.17.1 |
41-
| <a name="provider_null"></a> [null](#provider\_null) | 3.2.1 |
40+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 6.31.0 |
41+
| <a name="provider_null"></a> [null](#provider\_null) | 3.2.4 |
4242

4343
## Modules
4444

@@ -53,6 +53,7 @@ No modules.
5353
| [aws_iam_policy.athena](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
5454
| [aws_s3_bucket.athena_results](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
5555
| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
56+
| [aws_s3_bucket_lifecycle_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource |
5657
| [aws_s3_bucket_logging.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_logging) | resource |
5758
| [aws_s3_bucket_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
5859
| [aws_s3_bucket_public_access_block.athena_results](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
@@ -76,11 +77,13 @@ No modules.
7677
| <a name="input_bucket_name"></a> [bucket\_name](#input\_bucket\_name) | Name to apply to bucket (use `bucket_name` or `bucket_suffix`) | `string` | `null` | no |
7778
| <a name="input_bucket_suffix"></a> [bucket\_suffix](#input\_bucket\_suffix) | Suffix to apply to the bucket (use `bucket_name` or `bucket_suffix`). When using `bucket_suffix`, the bucket name will be `[ACCOUNT_ID]-[REGION]-s3logging-[BUCKET_SUFFIX].` | `string` | `"elblogging"` | no |
7879
| <a name="input_create_athena_query"></a> [create\_athena\_query](#input\_create\_athena\_query) | Create an Athena table for querying ALB logs. Uses the aws cli | `bool` | `false` | no |
79-
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | KMS key to encrypt bucket with. | `string` | `null` | no |
80-
| <a name="input_lifecycle_rules"></a> [lifecycle\_rules](#input\_lifecycle\_rules) | lifecycle rules to apply to the bucket | <pre>list(object(<br> {<br> id = string<br> enabled = bool<br> prefix = string<br> expiration = number<br> noncurrent_version_expiration = number<br> }))</pre> | `[]` | no |
80+
| <a name="input_lifecycle_rules"></a> [lifecycle\_rules](#input\_lifecycle\_rules) | lifecycle rules to apply to the bucket | <pre>list(object(<br/> {<br/> id = string<br/> enabled = bool<br/> prefix = string<br/> expiration = number<br/> noncurrent_version_expiration = number<br/> }))</pre> | `[]` | no |
8181
| <a name="input_s3_access_logging_bucket"></a> [s3\_access\_logging\_bucket](#input\_s3\_access\_logging\_bucket) | Optional target for S3 access logging | `string` | `null` | no |
8282
| <a name="input_s3_access_logging_prefix"></a> [s3\_access\_logging\_prefix](#input\_s3\_access\_logging\_prefix) | Optional target prefix for S3 access logging (only used if `s3_access_logging_bucket` is set) | `string` | `null` | no |
83+
| <a name="input_source_accounts"></a> [source\_accounts](#input\_source\_accounts) | List of AWS account IDs to restrict log delivery to. Defaults to caller account. Set to an empty list to allow any account. | `list(string)` | <pre>[<br/> "self"<br/>]</pre> | no |
84+
| <a name="input_source_organizations"></a> [source\_organizations](#input\_source\_organizations) | List of AWS Organization IDs to restrict log delivery to. Overrides `source_accounts`. | `list(string)` | `[]` | no |
8385
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to add to supported resources | `map(string)` | `{}` | no |
86+
| <a name="input_use_legacy_elb_policy"></a> [use\_legacy\_elb\_policy](#input\_use\_legacy\_elb\_policy) | Use the legacy ELB policy statement from pre-2022. | `bool` | `false` | no |
8487
| <a name="input_versioning_enabled"></a> [versioning\_enabled](#input\_versioning\_enabled) | Whether or not to use versioning on the bucket. This can be useful for audit purposes since objects in a logging bucket should not be updated. | `bool` | `true` | no |
8588

8689
## Outputs
@@ -91,4 +94,4 @@ No modules.
9194
| <a name="output_s3_bucket_arn"></a> [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | The ARN of the bucket |
9295
| <a name="output_s3_bucket_domain_name"></a> [s3\_bucket\_domain\_name](#output\_s3\_bucket\_domain\_name) | The domain name of the bucket |
9396
| <a name="output_s3_bucket_name"></a> [s3\_bucket\_name](#output\_s3\_bucket\_name) | The name of the bucket |
94-
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
97+
<!-- END_TF_DOCS -->

main.tf

Lines changed: 105 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,41 @@ locals {
1717
region = data.aws_region.current.name
1818
}
1919

20-
#trivy:ignore:avd-aws-0089
20+
#trivy:ignore:AVD-AWS-0089
2121
resource "aws_s3_bucket" "this" {
2222
bucket = local.bucket_name
2323
tags = var.tags
24+
}
25+
26+
resource "aws_s3_bucket_lifecycle_configuration" "this" {
27+
bucket = aws_s3_bucket.this.id
28+
transition_default_minimum_object_size = "varies_by_storage_class"
2429

25-
dynamic "lifecycle_rule" {
30+
dynamic "rule" {
2631
iterator = rule
2732
for_each = var.lifecycle_rules
2833

2934
content {
30-
id = rule.value.id
31-
enabled = rule.value.enabled
32-
prefix = lookup(rule.value, "prefix", null)
35+
id = rule.value.id
36+
status = rule.value.enabled ? "Enabled" : "Disabled"
37+
38+
dynamic "filter" {
39+
for_each = contains(keys(rule.value), "prefix") ? [true] : []
40+
content {
41+
prefix = rule.value.prefix
42+
}
43+
}
3344

3445
expiration {
3546
days = rule.value.expiration
3647
}
3748

3849
noncurrent_version_expiration {
39-
days = rule.value.noncurrent_version_expiration
50+
noncurrent_days = rule.value.noncurrent_version_expiration
4051
}
4152
}
4253
}
54+
4355
}
4456

4557
resource "aws_s3_bucket_versioning" "this" {
@@ -53,13 +65,13 @@ resource "aws_s3_bucket_versioning" "this" {
5365
}
5466
}
5567

68+
#trivy:ignore:AVD-AWS-0132
5669
resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
5770
bucket = aws_s3_bucket.this.id
5871

5972
rule {
6073
apply_server_side_encryption_by_default {
61-
kms_master_key_id = var.kms_key_id
62-
sse_algorithm = var.kms_key_id != null ? "aws:kms" : "AES256"
74+
sse_algorithm = "AES256"
6375
}
6476
}
6577
}
@@ -72,47 +84,118 @@ resource "aws_s3_bucket_public_access_block" "this" {
7284
restrict_public_buckets = true
7385
}
7486

87+
locals {
88+
real_source_accounts = [for a in var.source_accounts : a == "self" ? local.account_id : a]
89+
elb_source_accounts = length(var.source_organizations) > 0 ? ["*"] : sort(distinct(local.real_source_accounts))
90+
alb_source_arns = [for a in local.elb_source_accounts : "arn:aws:elasticloadbalancing:*:${a}:loadbalancer/*"]
91+
nlb_source_arns = [for a in local.elb_source_accounts : "arn:aws:logs:*:${a}:*"]
92+
}
93+
7594
data "aws_iam_policy_document" "this" {
76-
statement {
77-
sid = "AllowElbLogging"
78-
actions = ["s3:PutObject"]
79-
effect = "Allow"
80-
resources = ["arn:${local.partition}:s3:::${aws_s3_bucket.this.bucket}/*"]
8195

82-
principals {
83-
type = "AWS"
84-
identifiers = [data.aws_elb_service_account.principal.arn]
96+
dynamic "statement" {
97+
for_each = var.use_legacy_elb_policy ? [true] : []
98+
content {
99+
sid = "AllowElbLogging"
100+
actions = ["s3:PutObject"]
101+
effect = "Allow"
102+
resources = ["arn:${local.partition}:s3:::${aws_s3_bucket.this.bucket}/*"]
103+
104+
principals {
105+
type = "AWS"
106+
identifiers = [data.aws_elb_service_account.principal.arn]
107+
}
85108
}
86109
}
87110

111+
dynamic "statement" {
112+
for_each = var.use_legacy_elb_policy ? [] : [true]
113+
content {
114+
sid = "AllowAlbLogging"
115+
actions = ["s3:PutObject"]
116+
effect = "Allow"
117+
resources = ["arn:${local.partition}:s3:::${aws_s3_bucket.this.bucket}/*"]
118+
principals {
119+
type = "Service"
120+
identifiers = ["logdelivery.elasticloadbalancing.amazonaws.com"]
121+
}
122+
dynamic "condition" {
123+
for_each = length(local.alb_source_arns) > 0 ? [true] : []
124+
content {
125+
test = "ArnLike"
126+
variable = "aws:SourceArn"
127+
values = local.alb_source_arns
128+
}
129+
}
130+
dynamic "condition" {
131+
for_each = length(var.source_organizations) > 0 ? [true] : []
132+
content {
133+
test = "StringEquals"
134+
variable = "aws:SourceOrgId"
135+
values = var.source_organizations
136+
}
137+
}
138+
}
139+
}
88140
statement {
89141
sid = "AllowNlbLogging"
90142
actions = ["s3:PutObject"]
91143
effect = "Allow"
92144
resources = ["arn:${local.partition}:s3:::${aws_s3_bucket.this.bucket}/*"]
93-
145+
principals {
146+
type = "Service"
147+
identifiers = ["delivery.logs.amazonaws.com"]
148+
}
94149
condition {
95150
test = "StringEquals"
96151
variable = "s3:x-amz-acl"
97152
values = ["bucket-owner-full-control"]
98153
}
99-
100-
principals {
101-
type = "Service"
102-
identifiers = ["delivery.logs.amazonaws.com"]
154+
dynamic "condition" {
155+
for_each = length(local.nlb_source_arns) > 0 ? [true] : []
156+
content {
157+
test = "ArnLike"
158+
variable = "aws:SourceArn"
159+
values = local.nlb_source_arns
160+
}
103161
}
162+
dynamic "condition" {
163+
for_each = length(var.source_organizations) > 0 ? [true] : []
164+
content {
165+
test = "StringEquals"
166+
variable = "aws:ResourceOrgID"
167+
values = var.source_organizations
168+
}
169+
}
170+
104171
}
105172

106173
statement {
107174
sid = "AllowNlbLoggingAclAccess"
108-
actions = ["s3:GetBucketAcl"]
175+
actions = ["s3:GetBucketAcl", "s3:ListBucket"]
109176
effect = "Allow"
110177
resources = [aws_s3_bucket.this.arn]
111178

112179
principals {
113180
type = "Service"
114181
identifiers = ["delivery.logs.amazonaws.com"]
115182
}
183+
dynamic "condition" {
184+
for_each = length(local.nlb_source_arns) > 0 ? [true] : []
185+
content {
186+
test = "ArnLike"
187+
variable = "aws:SourceArn"
188+
values = local.nlb_source_arns
189+
}
190+
}
191+
dynamic "condition" {
192+
for_each = length(var.source_organizations) > 0 ? [true] : []
193+
content {
194+
test = "StringEquals"
195+
variable = "aws:ResourceOrgID"
196+
values = var.source_organizations
197+
}
198+
}
116199
}
117200
}
118201

variables.tf

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ variable "create_athena_query" {
1717
type = bool
1818
}
1919

20-
variable "kms_key_id" {
21-
default = null
22-
description = "KMS key to encrypt bucket with."
23-
type = string
24-
}
25-
2620
variable "lifecycle_rules" {
2721
default = []
2822
description = "lifecycle rules to apply to the bucket"
@@ -49,12 +43,30 @@ variable "s3_access_logging_prefix" {
4943
type = string
5044
}
5145

46+
variable "source_accounts" {
47+
default = ["self"]
48+
description = "List of AWS account IDs to restrict log delivery to. Defaults to caller account. Set to an empty list to allow any account."
49+
type = list(string)
50+
}
51+
52+
variable "source_organizations" {
53+
default = []
54+
description = "List of AWS Organization IDs to restrict log delivery to. Overrides `source_accounts`."
55+
type = list(string)
56+
}
57+
5258
variable "tags" {
5359
default = {}
5460
description = "Tags to add to supported resources"
5561
type = map(string)
5662
}
5763

64+
variable "use_legacy_elb_policy" {
65+
default = false
66+
description = "Use the legacy ELB policy statement from pre-2022."
67+
type = bool
68+
}
69+
5870
variable "versioning_enabled" {
5971
default = true
6072
description = "Whether or not to use versioning on the bucket. This can be useful for audit purposes since objects in a logging bucket should not be updated."

versions.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
terraform {
2-
required_version = ">= 0.13.4"
2+
required_version = ">= 1.5"
33

44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = ">= 3.8"
7+
version = ">= 5.0"
88
}
99
null = {
1010
source = "hashicorp/null"

0 commit comments

Comments
 (0)