Skip to content

Commit

Permalink
feat(Terraform): Changes infra config to add permissions for public a…
Browse files Browse the repository at this point in the history
…nd programmatic user to assets bucket
  • Loading branch information
KevSanchez committed Oct 29, 2024
1 parent e9a6a37 commit 1c433db
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 57 deletions.
21 changes: 15 additions & 6 deletions infrastructure/base/modules/bucket/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ resource "aws_s3_bucket_versioning" "asset_bucket_versioning" {
}
}

// this is commented, because we want to extend the policy it outside of the module
// if we declare the aws_s3_bucket_policy both here and outside the module, they will overwrite each other
// alternating every time the TF config is applied.
/*
resource "aws_s3_bucket_policy" "allow_access_from_another_account" {
bucket = aws_s3_bucket.bucket.id
policy = data.aws_iam_policy_document.allow_access_from_account.json
policy = data.aws_iam_policy_document.base_bucket_policy.json
}
*/

resource "aws_s3_bucket_cors_configuration" "bucket_cors_configuration" {
bucket = aws_s3_bucket.bucket.id
Expand All @@ -53,26 +58,30 @@ resource "aws_s3_bucket_public_access_block" "s3_bucket_public_access" {
bucket = aws_s3_bucket.bucket.id

block_public_acls = false
block_public_policy = true
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = true
restrict_public_buckets = false
}

data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "allow_access_from_account" {
// Base bucket policy with access from all identities in the account
data "aws_iam_policy_document" "base_bucket_policy" {
statement {
sid = "accountAccess"

principals {
type = "AWS"
identifiers = [data.aws_caller_identity.current.account_id]
}

actions = [
"s3:PutObject",
"s3:GetObject",
"s3:GetObject*",
"s3:ListBucket",
"s3:DeleteObject",
"s3:PutObjectAcl"
"s3:PutObjectAcl",
"s3:PutObjectTagging"
]

resources = [
Expand Down
12 changes: 12 additions & 0 deletions infrastructure/base/modules/bucket/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
output "bucket_name" {
value = aws_s3_bucket.bucket.bucket
}

output "bucket_id" {
value = aws_s3_bucket.bucket.id
}

output "bucket_policy" {
value = data.aws_iam_policy_document.base_bucket_policy
}

output "bucket_arn" {
value = aws_s3_bucket.bucket.arn
}
10 changes: 10 additions & 0 deletions infrastructure/base/modules/email/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,13 @@ resource "aws_iam_user_policy" "get_ecr_token_policy" {
]
})
}

// uncomment once the email identity has been verified
resource "aws_ses_domain_identity_verification" "domain_identity_verification" {
domain = var.domain
}

// The configuration must be manually set to the identity on the AWS console
resource "aws_ses_configuration_set" "email_configuration_set" {
name = "${var.project}-email-config-set"
}
5 changes: 5 additions & 0 deletions infrastructure/base/modules/email/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ variable "region" {
type = string
description = "A valid AWS region to house resources."
}

variable "project" {
type = string
description = "Name of the project"
}
78 changes: 78 additions & 0 deletions infrastructure/base/modules/env/bucket-config.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// ASSETS BUCKET
module "data_bucket" {
source = "../bucket"
bucket_name = "${var.project}-${var.environment}-assets-bucket"
domain = var.domain
}

//Extend the bucket policy to allow for public access from non-aws users (required by the FE to access the tiles directly)
data "aws_iam_policy_document" "extended_data_bucket_policy" {
source_policy_documents = [module.data_bucket.bucket_policy.json]

statement {
sid = "allowPublicAccess"
actions = ["s3:GetObject"]
effect = "Allow"
principals {
identifiers = ["*"]
type = "AWS"
}
resources = [
"${module.data_bucket.bucket_arn}",
"${module.data_bucket.bucket_arn}/*"
]
}
}

resource "aws_s3_bucket_policy" "data_bucket_policy" {
bucket = module.data_bucket.bucket_id
policy = data.aws_iam_policy_document.extended_data_bucket_policy.json
}


// Policy to allow access from specific roles/identities (programatic uploader, ec2, etc)
data "aws_iam_policy_document" "asset_bucket_read_write_policy_document" {
statement {
actions = [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:PutObjectAcl"
]
effect = "Allow"
resources = [
"${module.data_bucket.bucket_arn}",
"${module.data_bucket.bucket_arn}/*"
]
}
}


resource "aws_iam_policy" "asset_bucket_read_write_policy" {
name = "${title(var.project)}${title(var.environment)}BucketReaderWriter"
path = "/"
description = "Allows read access to the data layer bucket"

policy = data.aws_iam_policy_document.asset_bucket_read_write_policy_document.json
}

resource "aws_iam_role_policy_attachment" "beanstalk_ec2_worker" {
role = module.beanstalk.eb_role_id
policy_arn = aws_iam_policy.asset_bucket_read_write_policy.arn
}

// USER KEYS/SECRET FOR ASSETS BUCKET (programmatic use)
// This user is created mostly for convenience to be used by a custom script to upload large quantity of files
resource "aws_iam_user" "programmatic_asset_user" {
name = "${replace(title(replace(var.project, "/\\W/", "")), " ","")}AssetUser"
}

resource "aws_iam_access_key" "programmatic_asset_user_access_key" {
user = aws_iam_user.programmatic_asset_user.name
}

resource "aws_iam_user_policy_attachment" "programmatic_asset_user_policy" {
user = aws_iam_user.programmatic_asset_user.name
policy_arn = aws_iam_policy.asset_bucket_read_write_policy.arn
}
16 changes: 9 additions & 7 deletions infrastructure/base/modules/env/env_gh_values.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,15 @@ locals {

cms_variable_map_with_unprefixed_keys = {
CMS_URL = local.cms_lb_url

DATABASE_CLIENT = "postgres"
DATABASE_HOST = module.postgresql.host
DATABASE_PORT = module.postgresql.port
DATABASE_NAME = module.postgresql.db_name
DATABASE_USERNAME = module.postgresql.username

AWS_REGION = var.aws_region
AWS_SES_DOMAIN = var.domain
}
cms_secret_map_with_unprefixed_keys = {
HOST = "0.0.0.0"
Expand All @@ -65,17 +74,10 @@ locals {
TRANSFER_TOKEN_SALT = random_password.transfer_token_salt.result
JWT_SECRET = random_password.jwt_secret.result

DATABASE_CLIENT = "postgres"
DATABASE_HOST = module.postgresql.host
DATABASE_PORT = module.postgresql.port
DATABASE_NAME = module.postgresql.db_name
DATABASE_USERNAME = module.postgresql.username
DATABASE_PASSWORD = module.postgresql.password
DATABASE_SSL = true
DATABASE_SSL_REJECT_UNAUTHORIZED = false

AWS_REGION = var.aws_region
AWS_SES_DOMAIN = var.domain
AWS_SES_ACCESS_KEY_ID = aws_iam_access_key.email_user_access_key.id
AWS_SES_ACCESS_KEY_SECRET = aws_iam_access_key.email_user_access_key.secret
}
Expand Down
49 changes: 5 additions & 44 deletions infrastructure/base/modules/env/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ resource "aws_security_group_rule" "port_forward_postgres" {
}

module "email" {
source = "../email"
source = "../email"

domain = var.domain
region = var.aws_region
domain = var.domain
region = var.aws_region
project = var.project
}

resource "aws_iam_access_key" "email_user_access_key" {
Expand Down Expand Up @@ -107,44 +108,4 @@ module "beanstalk" {
domain = var.domain
acm_certificate = var.environment != "production" ? aws_acm_certificate.acm_certificate : data.aws_acm_certificate.acm_certificate
elasticbeanstalk_iam_service_linked_role_name = var.elasticbeanstalk_iam_service_linked_role_name
}


// TILER ASSETS BUCKET
module "data_bucket" {
source = "../bucket"
bucket_name = "${var.project}-${var.environment}-assets-bucket"
domain = var.domain
}

resource "aws_iam_policy" "policy" {
name = "${title(var.project)}${title(var.environment)}BucketReaderWriter"
path = "/"
description = "Allows read access to the data layer bucket"

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject",
"s3:PutObjectAcl"
]
Effect = "Allow"
Resource = [
"arn:aws:s3:::${module.data_bucket.bucket_name}/*",
"arn:aws:s3:::${module.data_bucket.bucket_name}"
]
},
]
})
}

resource "aws_iam_policy_attachment" "beanstalk_ec2_worker" {
name = "${var.project}-${var.environment}-s3-data-reader-writer"
roles = [module.beanstalk.eb_role_id]
policy_arn = aws_iam_policy.policy.arn
}
}
8 changes: 8 additions & 0 deletions infrastructure/base/modules/env/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,11 @@ output "email_iam_user_access_key_id" {
output "email_iam_user_access_key_secret" {
value = aws_iam_access_key.email_user_access_key.secret
}

output "programmatic_asset_user_access_key_id" {
value = aws_iam_access_key.programmatic_asset_user_access_key.id
}

output "programmatic_asset_user_access_key_secret" {
value = aws_iam_access_key.programmatic_asset_user_access_key.secret
}
19 changes: 19 additions & 0 deletions infrastructure/base/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ output "staging_postgresql_port" {
value = module.staging.postgresql_port
}


output "programmatic_asset_user_access_key" {
value = module.staging.programmatic_asset_user_access_key_id
}
output "programmatic_asset_user_access_secret" {
sensitive = true
value = module.staging.programmatic_asset_user_access_key_secret
}

output "staging_dns_entries" {
value = concat([
{
Expand Down Expand Up @@ -80,3 +89,13 @@ output "acm_certificate_domain_validation_options" {
# }
# ])
# }


output "postgresql_username" {
value = module.staging.postgresql_username
}

output "postgresql_password" {
sensitive = true
value = module.staging.postgresql_password
}

0 comments on commit 1c433db

Please sign in to comment.