diff --git a/release-oct-2025/terraform/.gitignore b/release-oct-2025/terraform/.gitignore new file mode 100644 index 0000000..05b2a76 --- /dev/null +++ b/release-oct-2025/terraform/.gitignore @@ -0,0 +1,32 @@ +# Source: https://github.com/github/gitignore/blob/main/Terraform.gitignore +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Ignore transient lock info files created by terraform apply +.terraform.tfstate.lock.info + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + diff --git a/release-oct-2025/terraform/.metadata b/release-oct-2025/terraform/.metadata new file mode 100644 index 0000000..bb25d2d --- /dev/null +++ b/release-oct-2025/terraform/.metadata @@ -0,0 +1,7 @@ +{ + "app_stack_name": "testAppstack", + "iac_type": "Terraform", + "provider": "aws", + "multi_env": false, + "exporter": "terraform" +} \ No newline at end of file diff --git a/release-oct-2025/terraform/README.md b/release-oct-2025/terraform/README.md new file mode 100644 index 0000000..34af970 --- /dev/null +++ b/release-oct-2025/terraform/README.md @@ -0,0 +1,3 @@ +# README +This is a readme file for IaC generated with StackGen. +You can modify your appStack -> [here](http://appcd.local/appstacks/2b8733ba-46fb-4f85-a5f5-185152306cda) diff --git a/release-oct-2025/terraform/main.tf b/release-oct-2025/terraform/main.tf new file mode 100644 index 0000000..b05dff4 --- /dev/null +++ b/release-oct-2025/terraform/main.tf @@ -0,0 +1,57 @@ +module "stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d" { + source = "./modules/aws_s3" + block_public_access = true + bucket_name = "test-appstack-bucket" + bucket_policy = "" + enable_versioning = true + enable_website_configuration = false + sse_algorithm = "aws:kms" + tags = { + release = "oct-2025" + } + website_error_document = "404.html" + website_index_document = "index.html" +} + +module "stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf" { + source = "./modules/aws_s3" + block_public_access = true + bucket_name = "aws-athena-bucket-892323" + bucket_policy = "" + enable_versioning = true + enable_website_configuration = false + sse_algorithm = "aws:kms" + tags = { + release = "oct-2025" + } + website_error_document = "404.html" + website_index_document = "index.html" +} + +module "stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67" { + source = "./modules/aws_athena" + athena_engine_version = "AUTO" + bucket_name = module.stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d.bucket_name + bytes_scanned_cutoff_per_query = 10485760 + database_force_destroy = false + database_name = "testappstack" + encrypt_query_results = true + encryption_option = "SSE_KMS" + expected_bucket_owner = null + kms_key = null + query = "testAppstackQuery" + query_description = null + query_name = "testAppstackWueryName" + query_results_encryption_option = "SSE_KMS" + require_encryption_configuration = false + result_output_location = null + set_acl_configuration = false + tags = { + release = "oct-2025" + } + workgroup_description = "testAppstackWD" + workgroup_force_destroy = false + workgroup_name = "testAppstackWG" + workgroup_state = "ENABLED" +} + diff --git a/release-oct-2025/terraform/modules/aws_athena/aws_athena.tf b/release-oct-2025/terraform/modules/aws_athena/aws_athena.tf new file mode 100644 index 0000000..045f2c0 --- /dev/null +++ b/release-oct-2025/terraform/modules/aws_athena/aws_athena.tf @@ -0,0 +1,80 @@ +# named query resource +resource "aws_athena_named_query" "this" { + name = var.query_name + description = var.query_description + query = var.query + workgroup = aws_athena_workgroup.this.id + database = aws_athena_database.this.name +} + +# database resource +resource "aws_athena_database" "this" { + name = var.database_name + bucket = var.bucket_name + dynamic "acl_configuration" { + for_each = var.set_acl_configuration ? [1] : [] + content { + s3_acl_option = "BUCKET_OWNER_FULL_CONTROL" + } + } + + dynamic "encryption_configuration" { + for_each = var.require_encryption_configuration ? [1] : [] + content { + encryption_option = var.encryption_option + kms_key = var.kms_key + } + } + + expected_bucket_owner = var.expected_bucket_owner + force_destroy = var.database_force_destroy +} + +resource "aws_kms_key" "aws_athena-result" { + deletion_window_in_days = 7 + description = "Athena KMS Key" +} + +resource "aws_kms_key" "athena_result_encryption" { + count = var.encrypt_query_results && var.query_results_encryption_option != "SSE_S3" ? 1 : 0 + description = "Custom KMS key for Athena query result encryption." + enable_key_rotation = true +} + +# workgroup resource +resource "aws_athena_workgroup" "this" { + name = var.workgroup_name + description = var.workgroup_description + state = var.workgroup_state + force_destroy = var.workgroup_force_destroy + tags = var.tags + + configuration { + bytes_scanned_cutoff_per_query = var.bytes_scanned_cutoff_per_query + engine_version { + selected_engine_version = var.athena_engine_version + } + result_configuration { + dynamic "encryption_configuration" { + for_each = var.encrypt_query_results ? [1] : [] + content { + encryption_option = var.query_results_encryption_option + kms_key_arn = aws_kms_key.athena_result_encryption[0].arn + } + } + dynamic "acl_configuration" { + for_each = var.set_acl_configuration ? [1] : [] + content { + s3_acl_option = "BUCKET_OWNER_FULL_CONTROL" + } + } + output_location = var.result_output_location + } + } +} + + + + + + diff --git a/release-oct-2025/terraform/modules/aws_athena/outputs.tf.json b/release-oct-2025/terraform/modules/aws_athena/outputs.tf.json new file mode 100644 index 0000000..c82acb8 --- /dev/null +++ b/release-oct-2025/terraform/modules/aws_athena/outputs.tf.json @@ -0,0 +1,19 @@ +{ + "output": { + "arn": { + "description": "The value of the wg_arn output", + "sensitive": false, + "value": "${aws_athena_workgroup.this.arn}" + }, + "database_id": { + "description": "The value of the database_id output", + "sensitive": false, + "value": "${aws_athena_database.this.id}" + }, + "query_id": { + "description": "The value of the query_id output", + "sensitive": false, + "value": "${aws_athena_named_query.this.id}" + } + } +} \ No newline at end of file diff --git a/release-oct-2025/terraform/modules/aws_athena/variables.tf.json b/release-oct-2025/terraform/modules/aws_athena/variables.tf.json new file mode 100644 index 0000000..f272aae --- /dev/null +++ b/release-oct-2025/terraform/modules/aws_athena/variables.tf.json @@ -0,0 +1,161 @@ +{ + "variable": { + "athena_engine_version": [ + { + "default": "AUTO", + "description": "Requested Athena engine version.", + "nullable": false, + "type": "string" + } + ], + "bucket_name": [ + { + "description": "Name of S3 bucket to save the results of the query execution.", + "nullable": false, + "type": "string" + } + ], + "bytes_scanned_cutoff_per_query": [ + { + "default": 10485760, + "description": "The upper data usage limit (cutoff) for the amount of bytes a single query in a workgroup is allowed to scan.", + "nullable": false, + "type": "number" + } + ], + "database_force_destroy": [ + { + "default": false, + "description": "Whether to destroy all tables in the database when destroying the database resource.", + "nullable": false, + "type": "bool" + } + ], + "database_name": [ + { + "description": "Name of the database to create.", + "nullable": false, + "type": "string" + } + ], + "encrypt_query_results": [ + { + "default": true, + "description": "Specifies whether query results must be encrypted, for all queries that run in this workgroup.", + "nullable": false, + "type": "bool" + } + ], + "encryption_option": [ + { + "default": "SSE_KMS", + "description": "Type of key.", + "nullable": false, + "type": "string" + } + ], + "expected_bucket_owner": [ + { + "description": "AWS account ID that you expect to be the owner of the Amazon S3 bucket.", + "nullable": true, + "type": "string" + } + ], + "kms_key": [ + { + "description": "The ARN of the KMS key to be used to decrypt the data in S3.", + "nullable": true, + "type": "string" + } + ], + "query": [ + { + "description": "The query string.", + "nullable": false, + "type": "string" + } + ], + "query_description": [ + { + "description": "The description for the named query.", + "nullable": true, + "type": "string" + } + ], + "query_name": [ + { + "description": "The name of the query.", + "type": "string" + } + ], + "query_results_encryption_option": [ + { + "default": "SSE_KMS", + "description": "Type of encryption.", + "nullable": false, + "type": "string" + } + ], + "require_encryption_configuration": [ + { + "default": false, + "description": "Encryption key block AWS Athena uses to decrypt the data in S3.", + "nullable": false, + "type": "bool" + } + ], + "result_output_location": [ + { + "description": "The location in Amazon S3 where your query results are stored, such as s3://path/to/query/bucket/.", + "nullable": true, + "type": "string" + } + ], + "set_acl_configuration": [ + { + "default": false, + "description": "Should an Amazon S3 canned ACL be set to control ownership of stored query results.", + "nullable": false, + "type": "bool" + } + ], + "workgroup_description": [ + { + "description": "The description of the workgroup.", + "nullable": true, + "type": "string" + } + ], + "workgroup_force_destroy": [ + { + "default": false, + "description": "Option to delete the workgroup and its contents even if the workgroup contains any named queries.", + "nullable": false, + "type": "bool" + } + ], + "workgroup_name": [ + { + "description": "The name of the workgroup.", + "nullable": false, + "type": "string" + } + ], + "workgroup_state": [ + { + "default": "ENABLED", + "description": "The state of the workgroup.", + "nullable": false, + "type": "string" + } + ], + "tags": [ + { + "default": {}, + "description": "A map of tags to apply to the resources", + "type": "map(string)", + "nullable":true + } + ] + } +} \ No newline at end of file diff --git a/release-oct-2025/terraform/modules/aws_s3/aws_s3.tf b/release-oct-2025/terraform/modules/aws_s3/aws_s3.tf new file mode 100644 index 0000000..38bb649 --- /dev/null +++ b/release-oct-2025/terraform/modules/aws_s3/aws_s3.tf @@ -0,0 +1,105 @@ +resource "aws_s3_bucket" "this" { + bucket = var.bucket_name + tags = var.tags +} + +# create versioning for the bucket +resource "aws_s3_bucket_versioning" "this" { + # create this resource only if var.versioning is not empty + count = var.enable_versioning ? 1 : 0 + + bucket = aws_s3_bucket.this.id + + # enable versioning + versioning_configuration { + status = "Enabled" + } +} + +# Create a server-side encryption configuration for the bucket +resource "aws_s3_bucket_server_side_encryption_configuration" "this" { + # create this resource only if var.sse_algorithm is not empty + count = var.sse_algorithm != "" ? 1 : 0 + + bucket = aws_s3_bucket.this.id + + rule { + apply_server_side_encryption_by_default { + kms_master_key_id = var.sse_algorithm == "aws:kms" ? aws_kms_key.custom_s3_kms_key[0].key_id : null + sse_algorithm = var.sse_algorithm + } + } +} + +# block public access +resource "aws_s3_bucket_public_access_block" "this" { + + bucket = aws_s3_bucket.this.id + + block_public_acls = var.block_public_access + block_public_policy = var.block_public_access + ignore_public_acls = var.block_public_access + restrict_public_buckets = var.block_public_access +} + + +resource "aws_s3_bucket_website_configuration" "this" { + count = var.enable_website_configuration ? 1 : 0 + bucket = aws_s3_bucket.this.id + + index_document { + suffix = var.website_index_document + } + + error_document { + key = var.website_error_document + } +} + +resource "aws_s3_bucket_policy" "website_bucket_policy" { + count = var.enable_website_configuration ? 1 : 0 + bucket = aws_s3_bucket.this.id + policy = data.aws_iam_policy_document.website_bucket_policy[0].json +} + +data "aws_iam_policy_document" "website_bucket_policy" { + count = var.enable_website_configuration ? 1 : 0 + statement { + effect = "Allow" + principals { + type = "AWS" + identifiers = ["*"] + } + actions = ["s3:GetObject"] + resources = ["${aws_s3_bucket.this.arn}/*"] + + } +} + +resource "aws_s3_bucket_policy" "allow_access" { + count = var.bucket_policy != "" ? 1 : 0 + bucket = aws_s3_bucket.this.id + policy = var.bucket_policy +} + + +resource "aws_kms_key" "custom_s3_kms_key" { + count = var.sse_algorithm == "aws:kms" ? 1 : 0 + description = "Custom KMS key for s3 bucket encryption" + enable_key_rotation = true +} + +resource "aws_kms_alias" "a" { + count = var.sse_algorithm == "aws:kms" ? 1 : 0 + name = "alias/s3-${replace(aws_s3_bucket.this.bucket, ".", "-")}" + target_key_id = aws_kms_key.custom_s3_kms_key[0].key_id +} + + + + + + + + + diff --git a/release-oct-2025/terraform/modules/aws_s3/outputs.tf.json b/release-oct-2025/terraform/modules/aws_s3/outputs.tf.json new file mode 100644 index 0000000..b5bf317 --- /dev/null +++ b/release-oct-2025/terraform/modules/aws_s3/outputs.tf.json @@ -0,0 +1,24 @@ +{ + "output": { + "arn": { + "description": "The value of the arn output", + "sensitive": false, + "value": "${aws_s3_bucket.this.arn}" + }, + "bucket_name": { + "description": "The value of the bucket_name output", + "sensitive": false, + "value": "${aws_s3_bucket.this.id}" + }, + "bucket_website_endpoint": { + "description": "The value of the bucket_website_endpoint output", + "sensitive": false, + "value": "${var.enable_website_configuration ? aws_s3_bucket_website_configuration.this[0].website_endpoint : null}" + }, + "kms_arn": { + "description": "The value of the kms_arn output", + "sensitive": false, + "value": "${var.sse_algorithm == \"aws:kms\" ? aws_kms_key.custom_s3_kms_key[0].arn : null}" + } + } +} \ No newline at end of file diff --git a/release-oct-2025/terraform/modules/aws_s3/variables.tf.json b/release-oct-2025/terraform/modules/aws_s3/variables.tf.json new file mode 100644 index 0000000..bce1322 --- /dev/null +++ b/release-oct-2025/terraform/modules/aws_s3/variables.tf.json @@ -0,0 +1,72 @@ +{ + "variable": { + "block_public_access": [ + { + "default": true, + "description": "A state of block public access. If false, block public access is not enabled.", + "type": "bool", + "nullable": true + } + ], + "bucket_name": [ + { + "description": "The name of the s3 bucket", + "nullable": false, + "type": "string" + } + ], + "enable_versioning": [ + { + "default": true, + "description": "Enable versioning for the bucket", + "type": "bool", + "nullable": true + } + ], + "sse_algorithm": [ + { + "default": "aws:kms", + "description": "The server-side encryption algorithm to use. Valid values are AES256 and aws:kms. If you specify aws:kms, a new KMS key will be provisioned and used. If empty, no encryption is performed.", + "type": "string", + "nullable": true + } + ], + "enable_website_configuration": [ + { + "default": false, + "description": "Enable website configuration for the bucket", + "type": "bool" + } + ], + "website_index_document": [ + { + "description": "The index document for the bucket", + "type": "string", + "default": "index.html" + } + ], + "website_error_document": [ + { + "description": "The error document for the bucket", + "type": "string", + "default": "404.html" + } + ], + "bucket_policy": [ + { + "description": "The IAM policy of the bucket (can be used to allow access to other roles or accounts)", + "type": "string", + "default": "", + "nullable": true + } + ], + "tags": [ + { + "default": {}, + "description": "A mapping of AWS tags to assign to the bucket.", + "type": "map(string)", + "nullable": true + } + ] + } + } \ No newline at end of file diff --git a/release-oct-2025/terraform/outputs.tf b/release-oct-2025/terraform/outputs.tf new file mode 100644 index 0000000..5bacc68 --- /dev/null +++ b/release-oct-2025/terraform/outputs.tf @@ -0,0 +1,55 @@ +output "aws_athena_stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67_arn" { + value = module.stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67.arn + sensitive = false +} + +output "aws_athena_stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67_database_id" { + value = module.stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67.database_id + sensitive = false +} + +output "aws_athena_stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67_query_id" { + value = module.stackgen_f58d11ed-ea26-4c15-ab0e-bb981b9c2c67.query_id + sensitive = false +} + +output "aws_s3_stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf_arn" { + value = module.stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf.arn + sensitive = false +} + +output "aws_s3_stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf_bucket_name" { + value = module.stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf.bucket_name + sensitive = false +} + +output "aws_s3_stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf_bucket_website_endpoint" { + value = module.stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf.bucket_website_endpoint + sensitive = false +} + +output "aws_s3_stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf_kms_arn" { + value = module.stackgen_bb02b275-fa8a-439b-a00b-c1a9bcea82bf.kms_arn + sensitive = false +} + +output "aws_s3_stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d_arn" { + value = module.stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d.arn + sensitive = false +} + +output "aws_s3_stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d_bucket_name" { + value = module.stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d.bucket_name + sensitive = false +} + +output "aws_s3_stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d_bucket_website_endpoint" { + value = module.stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d.bucket_website_endpoint + sensitive = false +} + +output "aws_s3_stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d_kms_arn" { + value = module.stackgen_001a15e3-9cdb-4b92-b4dc-7e19e4adce6d.kms_arn + sensitive = false +} + diff --git a/release-oct-2025/terraform/provider.tf b/release-oct-2025/terraform/provider.tf new file mode 100644 index 0000000..f411dbd --- /dev/null +++ b/release-oct-2025/terraform/provider.tf @@ -0,0 +1,23 @@ +terraform { + required_version = ">= 1.0.0, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + + awscc = { // AWS Cloud Control + source = "hashicorp/awscc" + version = "~> 1.0" + } + } +} + +provider "awscc" { + region = var.region +} + +provider "aws" { + region = var.region +} diff --git a/release-oct-2025/terraform/variables.tf b/release-oct-2025/terraform/variables.tf new file mode 100644 index 0000000..60fa06c --- /dev/null +++ b/release-oct-2025/terraform/variables.tf @@ -0,0 +1,4 @@ +variable "region" { + description = "AWS region in which the project needs to be setup (us-east-1, ca-west-1, eu-west-3, etc)" +} +