diff --git a/terraform-encrypted-state/.terraform.lock.hcl b/terraform-encrypted-state/.terraform.lock.hcl new file mode 100644 index 0000000..c7d621e --- /dev/null +++ b/terraform-encrypted-state/.terraform.lock.hcl @@ -0,0 +1,37 @@ +# This file is maintained automatically by "tofu init". +# Manual edits may be lost in future updates. + +provider "registry.opentofu.org/hashicorp/aws" { + version = "6.1.0" + constraints = ">= 6.0.0" + hashes = [ + "h1:hEy/Eyxy7B9FD3LjYKWczJeiIyMhTKCPmrQyP7zscn4=", + "zh:3364a87565100ee1b34291722eef6fa2df2945d67c7dc0c51248f99ee1613ba7", + "zh:3c466112b14fd3744415b3835f637e5337294eb70b283639c88d4565eb43d27f", + "zh:6260c7f0de862ae64df26bc624578eb0c2f21de1e261388784a962e1e2cace3a", + "zh:68718a268ab9ec54ac5dcf50aaa11d556f95b8690f385c91d87454d8e4aa0e05", + "zh:a18d1bcdacf7a6fbd28dbb45c5ae0c518b592af2c2c38c46ffc819ab4f3bf48a", + "zh:bc223e51efcd60bc81763319df906fc863b6d51288e622c9d69e93d928ff2d72", + "zh:d768018fe7216977dd209a3ac9e7d0caf330b16510ff975ffa5fe17f4f62cbc5", + "zh:e770c6053c64d12fa29bcfc11ca9798e25c736cab2558bf444d92c2989b46b43", + "zh:f0e3afe56191a60a10f6dd3c7bd4ca39f662adfa6c8de04d507983c3c3ad9556", + ] +} + +provider "registry.opentofu.org/hashicorp/random" { + version = "3.7.2" + constraints = ">= 3.0.0" + hashes = [ + "h1:cFGCdxTlsrteTiaOV/iOQdql7eJkD3F/vtJxenkj9IE=", + "zh:2ffeb1058bd7b21a9e15a5301abb863053a2d42dffa3f6cf654a1667e10f4727", + "zh:519319ed8f4312ed76519652ad6cd9f98bc75cf4ec7990a5684c072cf5dd0a5d", + "zh:7371c2cc28c94deb9dba62fbac2685f7dde47f93019273a758dd5a2794f72919", + "zh:9b0ac4c1d8e36a86b59ced94fa517ae9b015b1d044b3455465cc6f0eab70915d", + "zh:c6336d7196f1318e1cbb120b3de8426ce43d4cacd2c75f45dba2dbdba666ce00", + "zh:c71f18b0cb5d55a103ea81e346fb56db15b144459123f1be1b0209cffc1deb4e", + "zh:d2dc49a6cac2d156e91b0506d6d756809e36bf390844a187f305094336d3e8d8", + "zh:d5b5fc881ccc41b268f952dae303501d6ec9f9d24ee11fe2fa56eed7478e15d0", + "zh:db9723eaca26d58c930e13fde221d93501529a5cd036b1f167ef8cff6f1a03cc", + "zh:fe3359f733f3ab518c6f85f3a9cd89322a7143463263f30321de0973a52d4ad8", + ] +} diff --git a/terraform-encrypted-state/kms.tf b/terraform-encrypted-state/kms.tf new file mode 100644 index 0000000..e2e230c --- /dev/null +++ b/terraform-encrypted-state/kms.tf @@ -0,0 +1,8 @@ +resource "aws_kms_key" "tf_state" { + description = "KMS key for Terraform/OpenTofu state encryption" +} + +output "kms_key_id" { + value = aws_kms_key.tf_state.key_id + description = "KMS key id" +} diff --git a/terraform-encrypted-state/main.tf b/terraform-encrypted-state/main.tf new file mode 100644 index 0000000..131dcaa --- /dev/null +++ b/terraform-encrypted-state/main.tf @@ -0,0 +1,20 @@ +# Generate a random password +resource "random_password" "main_password" { + length = 128 + special = false + upper = true + lower = true + numeric = true +} + +# Create AWS Secrets Manager secret +resource "aws_secretsmanager_secret" "main_password" { + name = "main-application-password" + description = "Main application password" +} + +# Store the password in the secret +resource "aws_secretsmanager_secret_version" "main_password" { + secret_id = aws_secretsmanager_secret.main_password.id + secret_string = random_password.main_password.result +} diff --git a/terraform-encrypted-state/providers.tofu b/terraform-encrypted-state/providers.tofu new file mode 100644 index 0000000..c125940 --- /dev/null +++ b/terraform-encrypted-state/providers.tofu @@ -0,0 +1,3 @@ +provider "aws" { + region = "us-east-1" +} diff --git a/terraform-encrypted-state/versions.tofu b/terraform-encrypted-state/versions.tofu new file mode 100644 index 0000000..411a1a7 --- /dev/null +++ b/terraform-encrypted-state/versions.tofu @@ -0,0 +1,36 @@ +terraform { + required_version = ">= 1.7" # Encrypted state available in OpenTofu 1.7 and later + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 6.0.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.0.0" + } + } + + encryption { + method "unencrypted" "migrate" {} # to support the current unencrypted state + + key_provider "aws_kms" "kms_key" { + kms_key_id = "INSERT_KMS_KEY_ID_HERE" + region = "us-east-1" + key_spec = "AES_256" + } + + method "aes_gcm" "kms" { + keys = key_provider.aws_kms.kms_key + } + + state { + method = method.aes_gcm.kms + fallback { + method = method.unencrypted.migrate + } + } + } + +} diff --git a/tf-ephemeral/.terraform.lock.hcl b/tf-ephemeral/.terraform.lock.hcl new file mode 100644 index 0000000..ce18778 --- /dev/null +++ b/tf-ephemeral/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "6.0.0" + constraints = ">= 6.0.0" + hashes = [ + "h1:dbRRZ1NzH1QV/+83xT/X3MLYaZobMXt8DNwbqnJojpo=", + "zh:16b1bb786719b7ebcddba3ab751b976ebf4006f7144afeebcb83f0c5f41f8eb9", + "zh:1fbc08b817b9eaf45a2b72ccba59f4ea19e7fcf017be29f5a9552b623eccc5bc", + "zh:304f58f3333dbe846cfbdfc2227e6ed77041ceea33b6183972f3f8ab51bd065f", + "zh:4cd447b5c24f14553bd6e1a0e4fea3c7d7b218cbb2316a3d93f1c5cb562c181b", + "zh:589472b56be8277558616075fc5480fcd812ba6dc70e8979375fc6d8750f83ef", + "zh:5d78484ba43c26f1ef6067c4150550b06fd39c5d4bfb790f92c4a6f7d9d0201b", + "zh:5f470ce664bffb22ace736643d2abe7ad45858022b652143bcd02d71d38d4e42", + "zh:7a9cbb947aaab8c885096bce5da22838ca482196cf7d04ffb8bdf7fd28003e47", + "zh:854df3e4c50675e727705a0eaa4f8d42ccd7df6a5efa2456f0205a9901ace019", + "zh:87162c0f47b1260f5969679dccb246cb528f27f01229d02fd30a8e2f9869ba2c", + "zh:9a145404d506b52078cd7060e6cbb83f8fc7953f3f63a5e7137d41f69d6317a3", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a4eab2649f5afe06cc406ce2aaf9fd44dcf311123f48d344c255e93454c08921", + "zh:bea09141c6186a3e133413ae3a2e3d1aaf4f43466a6a468827287527edf21710", + "zh:d7ea2a35ff55ddfe639ab3b04331556b772a8698eca01f5d74151615d9f336db", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = ">= 3.0.0" + hashes = [ + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/tf-ephemeral/ephemeral-resources.tf b/tf-ephemeral/ephemeral-resources.tf new file mode 100644 index 0000000..2cd4319 --- /dev/null +++ b/tf-ephemeral/ephemeral-resources.tf @@ -0,0 +1,15 @@ +ephemeral "random_password" "random_password_ephemeral" { + length = 16 + special = true + override_special = "!#$%&*()-_=+[]{}<>:?" +} + +resource "aws_secretsmanager_secret" "random_password_ephemeral_secret" { + name = "random_password_ephemeral_secret" +} + +resource "aws_secretsmanager_secret_version" "random_password_ephemeral_secret_version" { + secret_id = aws_secretsmanager_secret.random_password_ephemeral_secret.id + secret_string_wo = ephemeral.random_password.random_password_ephemeral.result + secret_string_wo_version = 1 +} diff --git a/tf-ephemeral/ephemeral-variables.tf b/tf-ephemeral/ephemeral-variables.tf new file mode 100644 index 0000000..8f314f0 --- /dev/null +++ b/tf-ephemeral/ephemeral-variables.tf @@ -0,0 +1,28 @@ +variable "api_key" { + sensitive = true # Still stored in state! + default = "xK9#mP2$vL@4qR7!nT6&wZ8*bY3^fH5j-EXAMPLE_SECRET_IN_PLAINTEXT" +} + +# Before - using sensitive (stored in state) +resource "aws_secretsmanager_secret_version" "sensitive_secret" { + secret_id = aws_secretsmanager_secret.sensitive_secret.id + secret_string = var.api_key # ❌ Regular attribute - stored in state! +} + +output "sensitive_secret" { + value = aws_secretsmanager_secret_version.sensitive_secret.secret_string + sensitive = true +} + + +variable "api_key_ephemeral" { + ephemeral = true # Never stored! + default = "wJalrXUtnFEMI/K7MDENG/bPxRfiCY-EXAMPLE_SECRET_WONT_BE_STORED" +} + +# After - using ephemeral (✅ never stored) +resource "aws_secretsmanager_secret_version" "ephemeral_secret" { + secret_id = aws_secretsmanager_secret.ephemeral_secret.id + secret_string_wo = var.api_key_ephemeral # ✅ Write only attribute - NOT stored! + secret_string_wo_version = 1 +} diff --git a/tf-ephemeral/main.tf b/tf-ephemeral/main.tf new file mode 100644 index 0000000..00853ba --- /dev/null +++ b/tf-ephemeral/main.tf @@ -0,0 +1,11 @@ +######################################################################################## +# Create the secrets in AWS Secrets Manager +# There is no secret stored in these resources. The actual secret is managed by the `aws_secretsmanager_secret_version` resource. +######################################################################################## +resource "aws_secretsmanager_secret" "sensitive_secret" { + name = "demo-sensitive-secret" +} + +resource "aws_secretsmanager_secret" "ephemeral_secret" { + name = "demo-ephemeral-secret" +} diff --git a/tf-ephemeral/providers.tf b/tf-ephemeral/providers.tf new file mode 100644 index 0000000..c125940 --- /dev/null +++ b/tf-ephemeral/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "us-east-1" +} diff --git a/tf-ephemeral/versions.tf b/tf-ephemeral/versions.tf new file mode 100644 index 0000000..696b59a --- /dev/null +++ b/tf-ephemeral/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.11.0" # Ephemeral resources and variables are only available in Terraform 1.11 and later + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 6.0.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.0.0" + } + } +}