diff --git a/infra/app/main.tf b/infra/app/main.tf index 255c85e..2941029 100644 --- a/infra/app/main.tf +++ b/infra/app/main.tf @@ -11,6 +11,8 @@ module "app_aws_s3_buckets" { source = "./modules/aws/s3/buckets" } -#module "project_aws_cloudfront_distribution" { +#module "app_aws_cloudfront_distribution" { # source = "./modules/aws/cloudfront/distribution" +# aws_s3_bucket_id_document = module.app_aws_s3_buckets.aws_s3_bucket_id_documents +# aws_s3_bucket_id_paste = module.app_aws_s3_buckets.aws_s3_bucket_id_paste #} diff --git a/infra/app/modules/aws/cloudfront/distribution/documentssstore.tf b/infra/app/modules/aws/cloudfront/distribution/documentssstore.tf index 8ba5a9a..45913a9 100644 --- a/infra/app/modules/aws/cloudfront/distribution/documentssstore.tf +++ b/infra/app/modules/aws/cloudfront/distribution/documentssstore.tf @@ -1,100 +1,100 @@ -#resource "aws_cloudfront_distribution" "s3_distribution" { -# origin { -# domain_name = aws_s3_bucket.b.bucket_regional_domain_name -# origin_access_control_id = aws_cloudfront_origin_access_control.default.id -# origin_id = local.s3_origin_id -# } -# -# enabled = true -# is_ipv6_enabled = true -# comment = "Some comment" -# -# logging_config { -# include_cookies = false -# bucket = "mylogs.s3.amazonaws.com" -# prefix = "myprefix" -# } -# -# aliases = ["mysite.example.com", "yoursite.example.com"] -# -# default_cache_behavior { -# allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] -# cached_methods = ["GET", "HEAD"] -# target_origin_id = local.s3_origin_id -# -# forwarded_values { -# query_string = false -# -# cookies { -# forward = "none" -# } -# } -# -# viewer_protocol_policy = "allow-all" -# min_ttl = 0 -# default_ttl = 3600 -# max_ttl = 86400 -# } -# -# # Cache behavior with precedence 0 -# ordered_cache_behavior { -# path_pattern = "/content/immutable/*" -# allowed_methods = ["GET", "HEAD", "OPTIONS"] -# cached_methods = ["GET", "HEAD", "OPTIONS"] -# target_origin_id = local.s3_origin_id -# -# forwarded_values { -# query_string = false -# headers = ["Origin"] -# -# cookies { -# forward = "none" -# } -# } -# -# min_ttl = 0 -# default_ttl = 86400 -# max_ttl = 31536000 -# compress = true -# viewer_protocol_policy = "redirect-to-https" -# } -# -# # Cache behavior with precedence 1 -# ordered_cache_behavior { -# path_pattern = "/content/*" -# allowed_methods = ["GET", "HEAD", "OPTIONS"] -# cached_methods = ["GET", "HEAD"] -# target_origin_id = local.s3_origin_id -# -# forwarded_values { -# query_string = false -# -# cookies { -# forward = "none" -# } -# } -# -# min_ttl = 0 -# default_ttl = 3600 -# max_ttl = 86400 -# compress = true -# viewer_protocol_policy = "redirect-to-https" -# } -# -# price_class = "PriceClass_200" -# -# restrictions { -# geo_restriction { -# restriction_type = "whitelist" -# locations = ["US", "CA", "GB", "DE"] -# } -# } -# -# tags = { -# Environment = "${var.environment}" -# } -# -# viewer_certificate { -# cloudfront_default_certificate = true -# } -#} +resource "aws_cloudfront_distribution" "s3_distribution" { + origin { + domain_name = aws_s3_bucket.b.bucket_regional_domain_name + origin_access_control_id = aws_cloudfront_origin_access_control.default.id + origin_id = "${var.aws_s3_bucket_id_document}" + } + + enabled = true + is_ipv6_enabled = true + comment = "Some comment" + + logging_config { + include_cookies = false + bucket = "mylogs.s3.amazonaws.com" + prefix = "myprefix" + } + + aliases = ["mysite.example.com", "yoursite.example.com"] + + default_cache_behavior { + allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] + cached_methods = ["GET", "HEAD"] + target_origin_id = "${var.aws_s3_bucket_id_document}" + + forwarded_values { + query_string = false + + cookies { + forward = "none" + } + } + + viewer_protocol_policy = "allow-all" + min_ttl = 0 + default_ttl = 3600 + max_ttl = 86400 + } + + # Cache behavior with precedence 0 + ordered_cache_behavior { + path_pattern = "/content/immutable/*" + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = local.s3_origin_id + + forwarded_values { + query_string = false + headers = ["Origin"] + + cookies { + forward = "none" + } + } + + min_ttl = 0 + default_ttl = 86400 + max_ttl = 31536000 + compress = true + viewer_protocol_policy = "redirect-to-https" + } + + # Cache behavior with precedence 1 + ordered_cache_behavior { + path_pattern = "/content/*" + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD"] + target_origin_id = local.s3_origin_id + + forwarded_values { + query_string = false + + cookies { + forward = "none" + } + } + + min_ttl = 0 + default_ttl = 3600 + max_ttl = 86400 + compress = true + viewer_protocol_policy = "redirect-to-https" + } + + price_class = "PriceClass_200" + + restrictions { + geo_restriction { + restriction_type = "whitelist" + locations = ["US", "CA", "GB", "DE"] + } + } + + tags = { + Environment = "${var.environment}" + } + + viewer_certificate { + cloudfront_default_certificate = true + } +} diff --git a/infra/app/modules/aws/cloudfront/distribution/origin_access_control.tf b/infra/app/modules/aws/cloudfront/distribution/origin_access_control.tf new file mode 100644 index 0000000..3b8c072 --- /dev/null +++ b/infra/app/modules/aws/cloudfront/distribution/origin_access_control.tf @@ -0,0 +1,7 @@ +#resource "aws_cloudfront_origin_access_control" "oac" { +# name = "${var.name}-oac" +# description = "${var.name}-Origine Access Control Policy" +# origin_access_control_origin_type = "s3" +# signing_behavior = "always" +# signing_protocol = "sigv4" +#} \ No newline at end of file diff --git a/infra/app/modules/aws/cloudfront/distribution/variables.tf b/infra/app/modules/aws/cloudfront/distribution/variables.tf index 00f14d7..b9b8039 100644 --- a/infra/app/modules/aws/cloudfront/distribution/variables.tf +++ b/infra/app/modules/aws/cloudfront/distribution/variables.tf @@ -18,3 +18,15 @@ variable "environment" { default = "test" } + +variable "aws_s3_bucket_id_document" { + type = string + description = "AWS region for all resources." + default = "" +} + +variable "aws_s3_bucket_id_paste" { + type = string + description = "AWS region for all resources." + default = "" +} diff --git a/infra/app/modules/aws/s3/buckets/documentssstore.tf b/infra/app/modules/aws/s3/buckets/document.tf similarity index 79% rename from infra/app/modules/aws/s3/buckets/documentssstore.tf rename to infra/app/modules/aws/s3/buckets/document.tf index 8e6ea90..40a3e5e 100644 --- a/infra/app/modules/aws/s3/buckets/documentssstore.tf +++ b/infra/app/modules/aws/s3/buckets/document.tf @@ -1,4 +1,4 @@ -resource "aws_s3_bucket" "documentssstore" { +resource "aws_s3_bucket" "document" { bucket = "documentssstore" tags = { @@ -10,14 +10,14 @@ resource "aws_s3_bucket" "documentssstore" { } resource "aws_s3_bucket_policy" "documentssstore_allow_access_from_cloudfront" { - bucket = aws_s3_bucket.documentssstore.id + bucket = aws_s3_bucket.document.id policy = data.aws_iam_policy_document.documentssstore_allow_access_from_cloudfront.json } data "aws_iam_policy_document" "documentssstore_allow_access_from_cloudfront" { statement { principals { - type = "AWS" + type = "Service" identifiers = ["cloudfront.amazonaws.com"] } @@ -26,8 +26,8 @@ data "aws_iam_policy_document" "documentssstore_allow_access_from_cloudfront" { ] resources = [ - aws_s3_bucket.documentssstore.arn, - "${aws_s3_bucket.documentssstore.arn}/*", + aws_s3_bucket.document.arn, + "${aws_s3_bucket.document.arn}/*", ] condition { diff --git a/infra/app/modules/aws/s3/buckets/outputs.tf b/infra/app/modules/aws/s3/buckets/outputs.tf index e69de29..1fd2f89 100644 --- a/infra/app/modules/aws/s3/buckets/outputs.tf +++ b/infra/app/modules/aws/s3/buckets/outputs.tf @@ -0,0 +1,9 @@ +output "aws_s3_bucket_id_documents" { + value = aws_s3_bucket.document.id + description = "aws_s3_bucket_id_documents" +} + +output "aws_s3_bucket_id_paste" { + value = aws_s3_bucket.paste.id + description = "aws_s3_bucket_id_documents" +} \ No newline at end of file diff --git a/infra/app/modules/aws/s3/buckets/paste.tf b/infra/app/modules/aws/s3/buckets/paste.tf new file mode 100644 index 0000000..7f51a05 --- /dev/null +++ b/infra/app/modules/aws/s3/buckets/paste.tf @@ -0,0 +1,39 @@ +resource "aws_s3_bucket" "paste" { + bucket = "${var.s3_bucket_paste}" + + tags = { + Name = "${var.s3_bucket_paste}" + Owner = "${var.project_name}" + Environment = "${var.environment}" + Region = "${var.region}" + } +} + +resource "aws_s3_bucket_policy" "pastesss_allow_access_from_cloudfront" { + bucket = aws_s3_bucket.paste.id + policy = data.aws_iam_policy_document.pastesss_allow_access_from_cloudfront.json +} + +data "aws_iam_policy_document" "pastesss_allow_access_from_cloudfront" { + statement { + principals { + type = "Service" + identifiers = ["cloudfront.amazonaws.com"] + } + + actions = [ + "s3:GetObject", + ] + + resources = [ + aws_s3_bucket.paste.arn, + "${aws_s3_bucket.paste.arn}/*", + ] + + condition { + test = "StringEquals" + values = ["arn:aws:cloudfront::430689894701:distribution/E2ZI5IWQWTVER"] + variable = "AWS:SourceArn" + } + } +} \ No newline at end of file diff --git a/infra/app/modules/aws/s3/buckets/variables.tf b/infra/app/modules/aws/s3/buckets/variables.tf index 00f14d7..8e4b004 100644 --- a/infra/app/modules/aws/s3/buckets/variables.tf +++ b/infra/app/modules/aws/s3/buckets/variables.tf @@ -18,3 +18,9 @@ variable "environment" { default = "test" } + +variable "s3_bucket_paste" { + type = string + description = "Template service in java, spring-boot project." + default = "private-pastesss" +} diff --git a/infra/app/terraform.tfstate.backup b/infra/app/terraform.tfstate.backup new file mode 100644 index 0000000..3225f24 --- /dev/null +++ b/infra/app/terraform.tfstate.backup @@ -0,0 +1,305 @@ +{ + "version": 4, + "terraform_version": "1.7.2", + "serial": 16, + "lineage": "92e76432-a094-bf0a-9900-05dc816fa74e", + "outputs": {}, + "resources": [ + { + "module": "module.app_aws_s3_buckets", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "documentssstore_allow_access_from_cloudfront", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "1817664966", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": [\n \"arn:aws:s3:::documentssstore/*\",\n \"arn:aws:s3:::documentssstore\"\n ],\n \"Principal\": {\n \"AWS\": \"cloudfront.amazonaws.com\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"AWS:SourceArn\": \"arn:aws:cloudfront::430689894701:distribution/E2ZI5IWQWTVER\"\n }\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "s3:GetObject" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "arn:aws:cloudfront::430689894701:distribution/E2ZI5IWQWTVER" + ], + "variable": "AWS:SourceArn" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "cloudfront.amazonaws.com" + ], + "type": "AWS" + } + ], + "resources": [ + "arn:aws:s3:::documentssstore", + "arn:aws:s3:::documentssstore/*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.app_aws_s3_buckets", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "pastesss_allow_access_from_cloudfront", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "2149148865", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"s3:GetObject\",\n \"Resource\": [\n \"arn:aws:s3:::private-pastesss/*\",\n \"arn:aws:s3:::private-pastesss\"\n ],\n \"Principal\": {\n \"Service\": \"cloudfront.amazonaws.com\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"AWS:SourceArn\": \"arn:aws:cloudfront::430689894701:distribution/E2ZI5IWQWTVER\"\n }\n }\n }\n ]\n}", + "override_policy_documents": null, + "policy_id": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "s3:GetObject" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "arn:aws:cloudfront::430689894701:distribution/E2ZI5IWQWTVER" + ], + "variable": "AWS:SourceArn" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "cloudfront.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [ + "arn:aws:s3:::private-pastesss", + "arn:aws:s3:::private-pastesss/*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.app_aws_s3_buckets", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "documentssstore", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::documentssstore", + "bucket": "documentssstore", + "bucket_domain_name": "documentssstore.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "documentssstore.s3.ap-south-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "439d4f219779858a626daddec5046f541f2170faa60412fdb8988c7c51f52db8", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z11RGJOFQNVJUP", + "id": "documentssstore", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "ap-south-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": { + "Environment": "test", + "Name": "documentssstore", + "Owner": "template-service-java-spring-boot", + "Region": "ap-south-1" + }, + "tags_all": { + "Environment": "test", + "Name": "documentssstore", + "Owner": "template-service-java-spring-boot", + "Region": "ap-south-1" + }, + "timeouts": null, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19" + } + ] + }, + { + "module": "module.app_aws_s3_buckets", + "mode": "managed", + "type": "aws_s3_bucket", + "name": "paste", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "acceleration_status": "", + "acl": null, + "arn": "arn:aws:s3:::private-pastesss", + "bucket": "private-pastesss", + "bucket_domain_name": "private-pastesss.s3.amazonaws.com", + "bucket_prefix": "", + "bucket_regional_domain_name": "private-pastesss.s3.ap-south-1.amazonaws.com", + "cors_rule": [], + "force_destroy": false, + "grant": [ + { + "id": "439d4f219779858a626daddec5046f541f2170faa60412fdb8988c7c51f52db8", + "permissions": [ + "FULL_CONTROL" + ], + "type": "CanonicalUser", + "uri": "" + } + ], + "hosted_zone_id": "Z11RGJOFQNVJUP", + "id": "private-pastesss", + "lifecycle_rule": [], + "logging": [], + "object_lock_configuration": [], + "object_lock_enabled": false, + "policy": "", + "region": "ap-south-1", + "replication_configuration": [], + "request_payer": "BucketOwner", + "server_side_encryption_configuration": [ + { + "rule": [ + { + "apply_server_side_encryption_by_default": [ + { + "kms_master_key_id": "", + "sse_algorithm": "AES256" + } + ], + "bucket_key_enabled": false + } + ] + } + ], + "tags": { + "Environment": "test", + "Name": "private-pastesss", + "Owner": "template-service-java-spring-boot", + "Region": "ap-south-1" + }, + "tags_all": { + "Environment": "test", + "Name": "private-pastesss", + "Owner": "template-service-java-spring-boot", + "Region": "ap-south-1" + }, + "timeouts": null, + "versioning": [ + { + "enabled": false, + "mfa_delete": false + } + ], + "website": [], + "website_domain": null, + "website_endpoint": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19" + } + ] + }, + { + "module": "module.app_aws_s3_buckets", + "mode": "managed", + "type": "aws_s3_bucket_policy", + "name": "pastesss_allow_access_from_cloudfront", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "bucket": "private-pastesss", + "id": "private-pastesss", + "policy": "{\"Statement\":[{\"Action\":\"s3:GetObject\",\"Condition\":{\"StringEquals\":{\"AWS:SourceArn\":\"arn:aws:cloudfront::430689894701:distribution/E2ZI5IWQWTVER\"}},\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudfront.amazonaws.com\"},\"Resource\":[\"arn:aws:s3:::private-pastesss/*\",\"arn:aws:s3:::private-pastesss\"]}],\"Version\":\"2012-10-17\"}" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.app_aws_s3_buckets.aws_s3_bucket.paste", + "module.app_aws_s3_buckets.data.aws_iam_policy_document.pastesss_allow_access_from_cloudfront" + ] + } + ] + } + ], + "check_results": null +} diff --git a/src/main/java/code/shubham/core/document/services/factories/DocumentDownloadURLFactory.java b/src/main/java/code/shubham/core/document/services/factories/DocumentDownloadURLFactory.java deleted file mode 100644 index 9e75f50..0000000 --- a/src/main/java/code/shubham/core/document/services/factories/DocumentDownloadURLFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -package code.shubham.core.document.services.factories; - -import code.shubham.commons.aws.CloudFrontUtils; -import code.shubham.commons.aws.S3Utils; -import code.shubham.commons.enums.DownloadURLSource; -import code.shubham.commons.keystore.services.KeyService; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import java.security.NoSuchAlgorithmException; -import java.security.spec.InvalidKeySpecException; -import java.util.Date; - -@Component -@RequiredArgsConstructor -public class DocumentDownloadURLFactory { - - @Value("${aws.default.region}") - private String defaultRegion; - - @Value("${documents.bucket.name}") - private String defaultBucket; - - @Value("${documents.cdn.domain}") - private String cdnDomain; - - @Value("${documents.cdn.key.pair}") - private String cdnKeyPair; - - @Value("${documents.cdn.key.type}") - private String cdnKeyType; - - @Value("${documents.download.url.ttl.milliseconds}") - private Long downloadURLTTLInMilliseconds; - - private final KeyService keyService; - - public String get(final DownloadURLSource source, final String key) { - switch (source) { - case S3 -> { - return S3Utils.createPresignedGetUrl(this.defaultRegion, this.defaultBucket, key, - this.downloadURLTTLInMilliseconds); - } - case CLOUD_FRONT -> { - return CloudFrontUtils.signedURL(this.cdnDomain, key, this.cdnKeyPair, - this.keyService.getPrivateKeyWithPSec(this.cdnKeyType), - new Date(System.currentTimeMillis() + this.downloadURLTTLInMilliseconds)); - } - } - - return null; - } - -}