Skip to content

Commit

Permalink
feat: Add destination_aws_account_id for cross-account replication
Browse files Browse the repository at this point in the history
  • Loading branch information
baolsen committed Mar 6, 2023
1 parent 744f3df commit b832226
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 30 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ See [`CONTRIBUTING.md`](./.github/CONTRIBUTING.md) for further information.
|------|-------------|------|---------|:--------:|
| <a name="input_aws_iam_role_permissions_boundary"></a> [aws\_iam\_role\_permissions\_boundary](#input\_aws\_iam\_role\_permissions\_boundary) | AWS IAM Role permissions boundary. | `string` | `null` | no |
| <a name="input_create_iam_resources"></a> [create\_iam\_resources](#input\_create\_iam\_resources) | Whether to create IAM resources. | `bool` | `true` | no |
| <a name="input_destination_aws_account_id"></a> [destination\_aws\_account\_id](#input\_destination\_aws\_account\_id) | Destination AWS Account ID. Only use for cross-account replication. When specified, replica object ownership will be set to this account. | `string` | `null` | no |
| <a name="input_destination_bucket_kms_key_arn"></a> [destination\_bucket\_kms\_key\_arn](#input\_destination\_bucket\_kms\_key\_arn) | Destination S3 bucket KMS Key ARN | `string` | `null` | no |
| <a name="input_destination_bucket_name"></a> [destination\_bucket\_name](#input\_destination\_bucket\_name) | Destination S3 bucket name | `string` | n/a | yes |
| <a name="input_destination_bucket_region"></a> [destination\_bucket\_region](#input\_destination\_bucket\_region) | Destination S3 bucket region. If unspecified, then the provider region is used. | `string` | `null` | no |
| <a name="input_enable_delete_marker_replication"></a> [enable\_delete\_marker\_replication](#input\_enable\_delete\_marker\_replication) | Whether delete markers are replicated. | `bool` | `true` | no |
| <a name="input_enable_object_owner_override"></a> [enable\_object\_owner\_override](#input\_enable\_object\_owner\_override) | Whether to change replica object ownership to the destination account. Use when enabling cross-account replication. | `bool` | `false` | no |
| <a name="input_enable_replication_time_control_and_metrics"></a> [enable\_replication\_time\_control\_and\_metrics](#input\_enable\_replication\_time\_control\_and\_metrics) | Whether to enable S3 Replication Time Control (S3 RTC) and Replication Metrics. | `bool` | `false` | no |
| <a name="input_name_for_created_iam_resources"></a> [name\_for\_created\_iam\_resources](#input\_name\_for\_created\_iam\_resources) | Name for created IAM resources. | `string` | n/a | yes |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | S3 bucket prefix to replicate. | `string` | `""` | no |
Expand Down
4 changes: 2 additions & 2 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ data "aws_iam_policy_document" "replication_role_policy_document" {
}

dynamic "statement" {
for_each = var.enable_object_owner_override ? toset([1]) : toset([])
for_each = var.destination_aws_account_id != null ? toset([1]) : toset([])
content {
actions = ["s3:ObjectOwnerOverrideToBucketOwner"]
resources = ["${local.destination_bucket_arn}/*"]
Expand Down Expand Up @@ -146,7 +146,7 @@ data "aws_iam_policy_document" "destination_bucket_policy" {
}
dynamic "statement" {
for_each = var.enable_object_owner_override ? toset([1]) : toset([])
for_each = var.destination_aws_account_id != null ? toset([1]) : toset([])
content {
principals {
type = "AWS"
Expand Down
5 changes: 4 additions & 1 deletion examples/basic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ module "example" {
destination_bucket_kms_key_arn = aws_kms_key.destination.arn
tags = {}
depends_on = [
module.s3_bucket_source, module.s3_bucket_destination
]
}
```
----
Expand All @@ -99,7 +102,7 @@ module "example" {

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_profile"></a> [profile](#input\_profile) | AWS profile | `string` | n/a | yes |
| <a name="input_profile"></a> [profile](#input\_profile) | AWS profile | `string` | `null` | no |

----
### Modules
Expand Down
3 changes: 3 additions & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,7 @@ module "example" {
destination_bucket_kms_key_arn = aws_kms_key.destination.arn

tags = {}
depends_on = [
module.s3_bucket_source, module.s3_bucket_destination
]
}
1 change: 1 addition & 0 deletions examples/basic/variables.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
variable "profile" {
type = string
description = "AWS profile"
default = null
}
5 changes: 4 additions & 1 deletion examples/cross-region/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ module "example" {
tags = {}
depends_on = [
module.s3_bucket_source, module.s3_bucket_destination
]
}
```
----
Expand All @@ -102,7 +105,7 @@ module "example" {

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_profile"></a> [profile](#input\_profile) | AWS profile | `string` | n/a | yes |
| <a name="input_profile"></a> [profile](#input\_profile) | AWS profile | `string` | `null` | no |

----
### Modules
Expand Down
3 changes: 3 additions & 0 deletions examples/cross-region/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,7 @@ module "example" {

tags = {}

depends_on = [
module.s3_bucket_source, module.s3_bucket_destination
]
}
1 change: 1 addition & 0 deletions examples/cross-region/variables.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
variable "profile" {
type = string
description = "AWS profile"
default = null
}
26 changes: 18 additions & 8 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ resource "aws_s3_bucket_replication_configuration" "this" {
}
}

dynamic "access_control_translation" {
for_each = var.destination_aws_account_id != null ? toset([1]) : toset([])
content {
owner = "Destination"
}
}
account = var.destination_aws_account_id

replication_time {
status = var.enable_replication_time_control_and_metrics ? "Enabled" : "Disabled"
time {
Expand All @@ -76,20 +84,22 @@ resource "aws_s3_bucket_replication_configuration" "this" {
minutes = 15
}
}
}

dynamic "source_selection_criteria" {
for_each = var.source_bucket_kms_key_arn != null ? toset([1]) : toset([])
content {
sse_kms_encrypted_objects {
status = "Enabled"
}
}
}

delete_marker_replication {
status = var.enable_delete_marker_replication ? "Enabled" : "Disabled"
}

source_selection_criteria {
dynamic "sse_kms_encrypted_objects" {
for_each = var.source_bucket_kms_key_arn != null ? toset([1]) : toset([])
content {
status = "Enabled"
}
}
}


}
}
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def _get_tf(test_name, variables=None):
variables = variables or {}
with open(os.path.join(basedir, tfdir, "test.auto.tfvars.json"), "w") as f:
json.dump(variables, f)
tf.setup()
tf.setup(input=False)
return tf


Expand Down
8 changes: 4 additions & 4 deletions tests/test_examples_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ def output():
yield from terraform_apply_and_output(__name__)


def test_s3_replication_creation(profile, output):
source_bucket_name = output["module_s3_bucket_source"]["bucket_name"]
def test_s3_replication_creation(output):
source_bucket_name = output["module_s3_bucket_source"]["bucket"]
source_bucket_region = output["module_s3_bucket_source"]["region"]
destination_bucket_name = output["module_s3_bucket_destination"]["bucket_name"]
destination_bucket_name = output["module_s3_bucket_destination"]["bucket"]
destination_bucket_region = output["module_s3_bucket_source"]["region"]
assert source_bucket_region == destination_bucket_region

session = boto3.Session(profile_name=profile, region_name="af-south-1")
session = boto3.Session(region_name=source_bucket_region)
s3 = session.client("s3")

key = "test_replication"
Expand Down
12 changes: 6 additions & 6 deletions tests/test_examples_cross_region.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ def output():
yield from terraform_apply_and_output(__name__)


def test_s3_replication_creation(profile, output):
source_bucket_name = output["module_s3_bucket_source"]["bucket_name"]
def test_s3_replication_creation(output):
source_bucket_name = output["module_s3_bucket_source"]["bucket"]
source_bucket_region = output["module_s3_bucket_source"]["region"]
destination_bucket_name = output["module_s3_bucket_destination"]["bucket_name"]
destination_bucket_name = output["module_s3_bucket_destination"]["bucket"]
destination_bucket_region = output["module_s3_bucket_destination"]["region"]
assert source_bucket_region != destination_bucket_region
time.sleep(10)

session = boto3.Session(profile_name=profile)
s3_src = session.client("s3", region_name="af-south-1")
s3_dest = session.client("s3", region_name="eu-west-1")
session = boto3.Session()
s3_src = session.client("s3", region_name=source_bucket_region)
s3_dest = session.client("s3", region_name=destination_bucket_region)

key = "test_replication"
# Write an object to the source bucket
Expand Down
12 changes: 6 additions & 6 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ variable "destination_bucket_region" {
default = null
}

variable "destination_aws_account_id" {
description = "Destination AWS Account ID. Only use for cross-account replication. When specified, replica object ownership will be set to this account."
type = string
default = null
}

variable "tags" {
description = "Map of additional tags to assign to created resources. If configured with a provider `default_tags` configuration block present, tags with matching keys will overwrite those defined at the provider-level."
type = map(string)
Expand Down Expand Up @@ -87,12 +93,6 @@ variable "enable_replication_time_control_and_metrics" {
default = false
}

variable "enable_object_owner_override" {
description = "Whether to change replica object ownership to the destination account. Use when enabling cross-account replication."
type = bool
default = false
}

/*
variable "create_destination_resources" {
description = "Whether to create destination resources. Use when enabling cross-account replication."
Expand Down

0 comments on commit b832226

Please sign in to comment.