Skip to content

Commit

Permalink
ADD cross-region replication
Browse files Browse the repository at this point in the history
  • Loading branch information
ramesh-maddegoda committed Aug 30, 2024
1 parent ee5c561 commit adfaf90
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 5 deletions.
17 changes: 16 additions & 1 deletion terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,28 @@ module "common" {
mwaa_dag_s3_bucket_name = var.mwaa_dag_s3_bucket_name
}

# Terraform module to create archive for PDS Nucleus
# Terraform module to create primary archive for PDS Nucleus
module "archive" {
source = "./terraform-modules/archive"
pds_node_names = var.pds_node_names
depends_on = [module.common, module.ecs_ecr]
pds_nucleus_hot_archive_bucket_name_postfix = var.pds_nucleus_hot_archive_bucket_name_postfix
pds_nucleus_cold_archive_bucket_name_postfix = var.pds_nucleus_cold_archive_bucket_name_postfix
pds_nucleus_cold_archive_buckets = module.archive-secondary.pds_nucleus_cold_archive_buckets
permission_boundary_for_iam_roles = var.permission_boundary_for_iam_roles
pds_nucleus_cold_archive_storage_class = var.pds_nucleus_cold_archive_storage_class
}

# Terraform module to create secondary archive for PDS Nucleus
module "archive-secondary" {
source = "./terraform-modules/archive-secondary"
pds_node_names = var.pds_node_names
depends_on = [module.common, module.ecs_ecr]
pds_nucleus_cold_archive_bucket_name_postfix = var.pds_nucleus_cold_archive_bucket_name_postfix

providers = {
aws = aws.secondary
}
}

# The Terraform module to create the PDS Nucleus Baseline System (without any project specific components)
Expand Down
11 changes: 11 additions & 0 deletions terraform/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@ terraform {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
configuration_aliases = [ aws.secondary ]
}
}
}

provider "aws" {
region = var.region
default_tags {
tags = {
product = "PDS Nucleus"
}
}
}

provider "aws" {
region = var.region_secondary
alias = "secondary"

default_tags {
tags = {
Expand Down
20 changes: 20 additions & 0 deletions terraform/terraform-modules/archive-secondary/archive-secondary.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Terraform script to create the PDS archive related resources

# Create a cold archive for each PDS Node
resource "aws_s3_bucket" "pds_nucleus_cold_archive" {
count = length(var.pds_node_names)
# convert PDS node name to S3 bucket name compatible format
bucket = "${lower(replace(var.pds_node_names[count.index], "_", "-"))}-${var.pds_nucleus_cold_archive_bucket_name_postfix}"
}

resource "aws_s3_bucket_versioning" "pds_nucleus_cold_archive" {
count = length(var.pds_node_names)
bucket = aws_s3_bucket.pds_nucleus_cold_archive[count.index].id
versioning_configuration {
status = "Enabled"
}
}

output "pds_nucleus_cold_archive_buckets" {
value = aws_s3_bucket.pds_nucleus_cold_archive
}
12 changes: 12 additions & 0 deletions terraform/terraform-modules/archive-secondary/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
variable "pds_node_names" {
description = "List of PDS Node Names"
type = list(string)
sensitive = true
}

variable "pds_nucleus_cold_archive_bucket_name_postfix" {
description = "The postfix of the name of the cold archive s3 bucket"
default = "cold-archive-<venue-name>"
type = string
sensitive = true
}
104 changes: 100 additions & 4 deletions terraform/terraform-modules/archive/archive.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,105 @@ resource "aws_s3_bucket" "pds_nucleus_hot_archive" {
bucket = "${lower(replace(var.pds_node_names[count.index], "_", "-"))}-${var.pds_nucleus_hot_archive_bucket_name_postfix}"
}

# Create a cold archive for each PDS Node
resource "aws_s3_bucket" "pds_nucleus_cold_archive" {
resource "aws_s3_bucket_versioning" "pds_nucleus_hot_archive" {
count = length(var.pds_node_names)
# convert PDS node name to S3 bucket name compatible format
bucket = "${lower(replace(var.pds_node_names[count.index], "_", "-"))}-${var.pds_nucleus_cold_archive_bucket_name_postfix}"

bucket = aws_s3_bucket.pds_nucleus_hot_archive[count.index].id
versioning_configuration {
status = "Enabled"
}
}

data "aws_iam_policy_document" "pds_nucleus_archive_replication_assume_role" {
statement {
effect = "Allow"

principals {
type = "Service"
identifiers = ["s3.amazonaws.com"]
}

actions = ["sts:AssumeRole"]
}
}

# The Policy for Permission Boundary
data "aws_iam_policy" "mcp_operator_policy" {
name = var.permission_boundary_for_iam_roles
}

resource "aws_iam_role" "pds_nucleus_archive_replication_role" {
name = "pds-nucleus-archive-replication-role"
assume_role_policy = data.aws_iam_policy_document.pds_nucleus_archive_replication_assume_role.json
permissions_boundary = data.aws_iam_policy.mcp_operator_policy.arn
}

data "aws_iam_policy_document" "pds_nucleus_archive_replication_policy" {

statement {
effect = "Allow"

actions = [
"s3:GetReplicationConfiguration",
"s3:ListBucket",
]

resources = ["arn:aws:s3:::pds-*-archive-*"]
}

statement {
effect = "Allow"

actions = [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging",
]

resources = ["*"]
}

statement {
effect = "Allow"

actions = [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
]

resources = ["arn:aws:s3:::pds-*-archive-*"]
}
}

resource "aws_iam_policy" "pds_nucleus_archive_replication_policy" {
name = "pds-nucleus-archive-replication-policy"
policy = data.aws_iam_policy_document.pds_nucleus_archive_replication_policy.json
}

resource "aws_iam_role_policy_attachment" "pds_nucleus_archive_replication_policy_document" {
role = aws_iam_role.pds_nucleus_archive_replication_role.name
policy_arn = aws_iam_policy.pds_nucleus_archive_replication_policy.arn
}

resource "aws_s3_bucket_replication_configuration" "pds_nucleus_s3_bucket_replication_configuration" {

count = length(var.pds_node_names)

# Must have bucket versioning enabled first
depends_on = [aws_s3_bucket_versioning.pds_nucleus_hot_archive]

role = aws_iam_role.pds_nucleus_archive_replication_role.arn
bucket = aws_s3_bucket.pds_nucleus_hot_archive[count.index].id

rule {
id = "pds-nucleus-replication-rule-${var.pds_node_names[count.index]}"

status = "Enabled"

destination {
bucket = var.pds_nucleus_cold_archive_buckets[count.index].arn
storage_class = var.pds_nucleus_cold_archive_storage_class
}
}
}
17 changes: 17 additions & 0 deletions terraform/terraform-modules/archive/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,20 @@ variable "pds_nucleus_cold_archive_bucket_name_postfix" {
type = string
sensitive = true
}

variable "pds_nucleus_cold_archive_buckets" {
description = "The list of the names of the cold archive s3 buckets"
type = list
sensitive = true
}

variable "pds_nucleus_cold_archive_storage_class" {
description = "The storage class of the cold archive s3 buckets"
type = string
}

variable "permission_boundary_for_iam_roles" {
description = "Permission boundary for IAM roles"
type = string
sensitive = true
}
12 changes: 12 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ variable "region" {
default = "us-west-2"
}

variable "region_secondary" {
description = "Secondary Region for Archive"
type = string
default = "us-east-2"
}

variable "vpc_id" {
description = "VPC ID"
type = string
Expand Down Expand Up @@ -67,6 +73,12 @@ variable "pds_nucleus_cold_archive_bucket_name_postfix" {
sensitive = true
}

variable "pds_nucleus_cold_archive_storage_class" {
description = "The storage class of the cold archive s3 buckets"
default = "DEEP_ARCHIVE"
type = string
}

variable "pds_nucleus_config_bucket_name" {
description = "PDS Nucleus Configuration S3 Bucket Name"
default = "pds-nucleus-config-<venue-name>"
Expand Down

0 comments on commit adfaf90

Please sign in to comment.