Skip to content

Commit

Permalink
feat: upgrade AWS provider to v4.0+ (#57)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: resources regarding S3 bucket configurations need manual
imports after upgrade. See `docs/upgrade-1.0.md` for guidance.
  • Loading branch information
nozaq authored Feb 12, 2022
1 parent 642ccbf commit 271204c
Show file tree
Hide file tree
Showing 7 changed files with 410 additions and 275 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,24 @@ terraform {

See [the official document](https://www.terraform.io/docs/backends/types/s3.html#example-configuration) for more detail.

## Compatibility

- Starting from v1.0, this module requires [Terraform Provider for AWS](https://github.com/terraform-providers/terraform-provider-aws) v4.0 or later. [Version 1.0 Upgrade Guide](./docs/upgrade-1.0.md) described the recommended procedure after the upgrade.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.1.4 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.39.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.39.0 |
| <a name="provider_aws.replica"></a> [aws.replica](#provider\_aws.replica) | >= 3.39.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.0 |
| <a name="provider_aws.replica"></a> [aws.replica](#provider\_aws.replica) | >= 4.0 |

## Inputs

Expand Down
316 changes: 47 additions & 269 deletions bucket.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
locals {
define_lifecycle_rule = var.noncurrent_version_expiration != null || length(var.noncurrent_version_transitions) > 0
replication_role_count = var.iam_role_arn == null && var.enable_replication ? 1 : 0
define_lifecycle_rule = var.noncurrent_version_expiration != null || length(var.noncurrent_version_transitions) > 0
}

data "aws_region" "state" {
}

#---------------------------------------------------------------------------------------------------
Expand All @@ -15,121 +17,6 @@ resource "aws_kms_key" "this" {
tags = var.tags
}

resource "aws_kms_key" "replica" {
count = var.enable_replication ? 1 : 0
provider = aws.replica

description = var.kms_key_description
deletion_window_in_days = var.kms_key_deletion_window_in_days
enable_key_rotation = var.kms_key_enable_key_rotation

tags = var.tags
}

# IAM Role for Replication
# https://docs.aws.amazon.com/AmazonS3/latest/dev/crr-replication-config-for-kms-objects.html
resource "aws_iam_role" "replication" {
count = local.replication_role_count

name_prefix = var.iam_role_name_prefix
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Effect": "Allow"
}
]
}
POLICY

tags = var.tags
}

resource "aws_iam_policy" "replication" {
count = local.replication_role_count

name_prefix = var.iam_policy_name_prefix
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetReplicationConfiguration",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"${aws_s3_bucket.state.arn}"
]
},
{
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl"
],
"Effect": "Allow",
"Resource": [
"${aws_s3_bucket.state.arn}/*"
]
},
{
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete"
],
"Effect": "Allow",
"Resource": "${aws_s3_bucket.replica[0].arn}/*"
},
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "${aws_kms_key.this.arn}",
"Condition": {
"StringLike": {
"kms:ViaService": "s3.${data.aws_region.state.name}.amazonaws.com",
"kms:EncryptionContext:aws:s3:arn": [
"${aws_s3_bucket.state.arn}/*"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:GenerateDataKey"
],
"Resource": "${aws_kms_key.replica[0].arn}",
"Condition": {
"StringLike": {
"kms:ViaService": "s3.${data.aws_region.replica[0].name}.amazonaws.com",
"kms:EncryptionContext:aws:s3:arn": [
"${aws_s3_bucket.replica[0].arn}/*"
]
}
}
}
]
}
POLICY
}

resource "aws_iam_policy_attachment" "replication" {
count = local.replication_role_count

name = var.iam_policy_attachment_name
roles = [aws_iam_role.replication[0].name]
policy_arn = aws_iam_policy.replication[0].arn
}

#---------------------------------------------------------------------------------------------------
# Bucket Policies
#---------------------------------------------------------------------------------------------------
Expand All @@ -155,191 +42,82 @@ data "aws_iam_policy_document" "state_force_ssl" {
}
}

data "aws_iam_policy_document" "replica_force_ssl" {
count = var.enable_replication ? 1 : 0

statement {
sid = "AllowSSLRequestsOnly"
actions = ["s3:*"]
effect = "Deny"
resources = [
aws_s3_bucket.replica[0].arn,
"${aws_s3_bucket.replica[0].arn}/*"
]
condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["false"]
}
principals {
type = "*"
identifiers = ["*"]
}
}
}
#---------------------------------------------------------------------------------------------------
# Buckets
# Bucket
#---------------------------------------------------------------------------------------------------

data "aws_region" "state" {
}
resource "aws_s3_bucket_policy" "state_force_ssl" {
bucket = aws_s3_bucket.state.id
policy = data.aws_iam_policy_document.state_force_ssl.json

data "aws_region" "replica" {
count = var.enable_replication ? 1 : 0
provider = aws.replica
depends_on = [aws_s3_bucket_public_access_block.state]
}

resource "aws_s3_bucket" "replica" {
count = var.enable_replication ? 1 : 0
provider = aws.replica

bucket_prefix = var.override_s3_bucket_name ? null : var.replica_bucket_prefix
bucket = var.override_s3_bucket_name ? var.s3_bucket_name_replica : null
resource "aws_s3_bucket" "state" {
bucket_prefix = var.override_s3_bucket_name ? null : var.state_bucket_prefix
bucket = var.override_s3_bucket_name ? var.s3_bucket_name : null
force_destroy = var.s3_bucket_force_destroy

versioning {
enabled = true
}

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.replica[0].arn
}
}
}

dynamic "lifecycle_rule" {
for_each = local.define_lifecycle_rule ? [true] : []

content {
enabled = true
dynamic "noncurrent_version_transition" {
for_each = var.noncurrent_version_transitions

content {
days = noncurrent_version_transition.value.days
storage_class = noncurrent_version_transition.value.storage_class
}
}
dynamic "noncurrent_version_expiration" {
for_each = var.noncurrent_version_expiration != null ? [var.noncurrent_version_expiration] : []

content {
days = noncurrent_version_expiration.value.days
}
}
}
}

tags = var.tags
}

resource "aws_s3_bucket_policy" "state_force_ssl" {
resource "aws_s3_bucket_acl" "state" {
bucket = aws_s3_bucket.state.id
policy = data.aws_iam_policy_document.state_force_ssl.json

depends_on = [aws_s3_bucket_public_access_block.state]
acl = "private"
}

resource "aws_s3_bucket_public_access_block" "replica" {
count = var.enable_replication ? 1 : 0
provider = aws.replica
resource "aws_s3_bucket_versioning" "state" {
bucket = aws_s3_bucket.state.id

bucket = aws_s3_bucket.replica[0].id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
versioning_configuration {
status = "Enabled"
}
}

resource "aws_s3_bucket" "state" {
bucket_prefix = var.override_s3_bucket_name ? null : var.state_bucket_prefix
bucket = var.override_s3_bucket_name ? var.s3_bucket_name : null
acl = "private"
force_destroy = var.s3_bucket_force_destroy
resource "aws_s3_bucket_logging" "state" {
count = var.s3_logging_target_bucket != null ? 1 : 0

versioning {
enabled = true
}
bucket = aws_s3_bucket.state.id
target_bucket = var.s3_logging_target_bucket
target_prefix = var.s3_logging_target_prefix
}

dynamic "logging" {
for_each = var.s3_logging_target_bucket != null ? [true] : []
content {
target_bucket = var.s3_logging_target_bucket
target_prefix = var.s3_logging_target_prefix
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "state" {
bucket = aws_s3_bucket.state.id

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.this.arn
}
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.this.arn
}
}
}

dynamic "replication_configuration" {
for_each = var.enable_replication == true ? [1] : []
content {
role = var.iam_role_arn != null ? var.iam_role_arn : aws_iam_role.replication[0].arn
resource "aws_s3_bucket_lifecycle_configuration" "state" {
count = local.define_lifecycle_rule ? 1 : 0
bucket = aws_s3_bucket.state.id

rules {
id = "replica_configuration"
prefix = ""
status = "Enabled"
rule {
id = "auto-archive"
status = "Enabled"

source_selection_criteria {
sse_kms_encrypted_objects {
enabled = true
}
}
dynamic "noncurrent_version_transition" {
for_each = var.noncurrent_version_transitions

destination {
bucket = aws_s3_bucket.replica[0].arn
storage_class = "STANDARD"
replica_kms_key_id = aws_kms_key.replica[0].arn
}
content {
noncurrent_days = noncurrent_version_transition.value.days
storage_class = noncurrent_version_transition.value.storage_class
}
}
}

dynamic "lifecycle_rule" {
for_each = local.define_lifecycle_rule ? [true] : []

content {
enabled = true
dynamic "noncurrent_version_transition" {
for_each = var.noncurrent_version_transitions

content {
days = noncurrent_version_transition.value.days
storage_class = noncurrent_version_transition.value.storage_class
}
}
dynamic "noncurrent_version_expiration" {
for_each = var.noncurrent_version_expiration != null ? [var.noncurrent_version_expiration] : []
dynamic "noncurrent_version_expiration" {
for_each = var.noncurrent_version_expiration != null ? [var.noncurrent_version_expiration] : []

content {
days = noncurrent_version_expiration.value.days
}
content {
noncurrent_days = noncurrent_version_expiration.value.days
}
}
}

tags = var.tags
}

resource "aws_s3_bucket_policy" "replica_force_ssl" {
count = var.enable_replication ? 1 : 0
provider = aws.replica

bucket = aws_s3_bucket.replica[0].id
policy = data.aws_iam_policy_document.replica_force_ssl[0].json

depends_on = [aws_s3_bucket_public_access_block.replica]
}

resource "aws_s3_bucket_public_access_block" "state" {
Expand Down
Loading

0 comments on commit 271204c

Please sign in to comment.