Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Secrets in the Cloud Terraform #297

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion scenarios/secrets_in_the_cloud/terraform/data.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
data "archive_file" "lambda_zip" {
type = "zip"
source_file = "lambda_handler.py"
source_file = "templates/lambda_handler.py"
output_path = "lambda_function_payload.zip"
}

data "aws_ami" "amazon_linux_2" {
most_recent = true

filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}

filter {
name = "architecture"
values = ["x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

filter {
name = "root-device-type"
values = ["ebs"]
}

filter {
name = "ena-support"
values = ["true"]
}

owners = ["amazon"]
}
12 changes: 4 additions & 8 deletions scenarios/secrets_in_the_cloud/terraform/dynamodb.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@
# 2. An AWS DynamoDB Entry (for the Access ID)
# 3. An AWS DynamoDB Entry (for the Secret Key)

locals {
dynamodb_suffix = replace(var.cgid, "/[^a-z0-9-.]/", "-")
}

resource "aws_dynamodb_table" "secrets_table" {
name = "secrets-table-${local.dynamodb_suffix}"
billing_mode = "PAY_PER_REQUEST"
hash_key = "key"
name = "secrets-table-${local.cgid_suffix}"
billing_mode = "PAY_PER_REQUEST"
hash_key = "key"

attribute {
name = "key"
Expand All @@ -19,7 +15,7 @@ resource "aws_dynamodb_table" "secrets_table" {

# Enable server-side encryption using the default AWS KMS key
server_side_encryption {
enabled = true
enabled = true
}

tags = {
Expand Down
43 changes: 6 additions & 37 deletions scenarios/secrets_in_the_cloud/terraform/ec2_instance.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,11 @@
# 4. An AWS Instance Resource
# 5. An AWS Security Group Resource

data "aws_ami" "amazon_linux_2" {
most_recent = true

filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}

filter {
name = "architecture"
values = ["x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

filter {
name = "root-device-type"
values = ["ebs"]
}

filter {
name = "ena-support"
values = ["true"]
}

owners = ["amazon"]
}

provider "tls" {}
resource "tls_private_key" "id_rsa" {
algorithm = "RSA"
rsa_bits = 2048
}

resource "aws_key_pair" "id_rsa" {
key_name = "idrsa-keypair"
public_key = tls_private_key.id_rsa.public_key_openssh
Expand All @@ -50,23 +19,23 @@ resource "aws_instance" "web_app" {
ami = data.aws_ami.amazon_linux_2.id
instance_type = "t2.micro"
key_name = aws_key_pair.id_rsa.key_name
subnet_id = aws_subnet.cg_subnet.id
subnet_id = aws_subnet.subnet.id

vpc_security_group_ids = [
aws_security_group.web_app_sg.id,
]

user_data = base64encode(templatefile("user_data.tpl", {
user_data = base64encode(templatefile("templates/user_data.tpl", {
aws_access_key_id = aws_iam_access_key.secrets_manager_user_key.id,
aws_secret_access_key = aws_iam_access_key.secrets_manager_user_key.secret,
private_key = tls_private_key.id_rsa.private_key_pem,
}))

# This sets the EC2 instance's IAM instance profile to the Dynamo DB profile created in iam.tf
iam_instance_profile = aws_iam_instance_profile.dynamodb_instance_profile.name

metadata_options {
http_tokens = "required"
http_tokens = "required"
http_endpoint = "enabled"
}

Expand All @@ -78,7 +47,7 @@ resource "aws_instance" "web_app" {
resource "aws_security_group" "web_app_sg" {
name = "web_app_sg-${var.cgid}"
description = "Allow inbound traffic to the web app and Vault"
vpc_id = aws_vpc.cg_vpc.id
vpc_id = aws_vpc.vpc.id

ingress {
from_port = 8080
Expand Down
66 changes: 18 additions & 48 deletions scenarios/secrets_in_the_cloud/terraform/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,19 @@ resource "aws_iam_policy" "low_priv_user_s3_policy" {
Version = "2012-10-17"
Statement = [
{
Action = [
"s3:ListAllMyBuckets"
]
Action = "s3:ListAllMyBuckets"
Effect = "Allow"
Resource = "*"
},
{
Action = [
"s3:ListBucket"
]
Action = "s3:ListBucket"
Effect = "Allow"
Resource = [aws_s3_bucket.cg-secrets-bucket.arn]
Resource = aws_s3_bucket.secrets_bucket.arn
},
{
Action = [
"s3:GetObject"
]
Action = "s3:GetObject"
Effect = "Allow"
Resource = ["${aws_s3_bucket.cg-secrets-bucket.arn}/*"]
Resource = "${aws_s3_bucket.secrets_bucket.arn}/*"
},
{
Action = [
Expand All @@ -66,7 +60,7 @@ resource "aws_iam_policy" "low_priv_user_s3_policy" {
"iam:ListAttachedUserPolicies"
]
Effect = "Allow"
Resource = [aws_iam_user.low_priv_user.arn]
Resource = aws_iam_user.low_priv_user.arn
}
]
})
Expand All @@ -85,16 +79,12 @@ resource "aws_iam_policy" "low_priv_user_lambda_policy" {
Version = "2012-10-17"
Statement = [
{
Action = [
"lambda:ListFunctions"
]
Action = "lambda:ListFunctions"
Effect = "Allow"
Resource = "*"
},
{
Action = [
"lambda:InvokeFunction"
]
Action = "lambda:InvokeFunction"
Effect = "Allow"
Resource = aws_lambda_function.this.arn
}
Expand All @@ -107,6 +97,7 @@ resource "aws_iam_user_policy_attachment" "low_priv_user_lambda_attachment" {
policy_arn = aws_iam_policy.low_priv_user_lambda_policy.arn
}


resource "aws_iam_user" "secrets_manager_user" {
name = "${var.cgid}-secrets-manager-user"
}
Expand All @@ -115,30 +106,28 @@ resource "aws_iam_access_key" "secrets_manager_user_key" {
user = aws_iam_user.secrets_manager_user.name
}

resource "aws_iam_role_policy" "lambda_role_policy" {
name = "lambda-role-policy-${var.cgid}"
role = aws_iam_role.lambda_execution.id
resource "aws_iam_user_policy" "secrets_manager_user_policy" {
name = "secrets-manager-policy-${var.cgid}"
user = aws_iam_user.secrets_manager_user.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"rds:Describe*",
"rds:List*"
"secretsmanager:ListSecrets",
"secretsmanager:DescribeSecret",
"secretsmanager:GetSecretValue"
]
Effect = "Allow"
Effect = "Allow"
Resource = "*"
},
{
Action = "secretsmanager:GetSecretValue"
Effect = "Allow"
Resource = aws_secretsmanager_secret.this.arn
}
]
})
}


# Is this even used?
resource "aws_iam_role" "secrets_manager_role" {
name = "secrets-manager-role-${var.cgid}"

Expand All @@ -156,25 +145,6 @@ resource "aws_iam_role" "secrets_manager_role" {
})
}

resource "aws_iam_user_policy" "secrets_manager_user_policy" {
name = "secrets-manager-policy-${var.cgid}"
user = aws_iam_user.secrets_manager_user.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"secretsmanager:ListSecrets",
"secretsmanager:DescribeSecret",
"secretsmanager:GetSecretValue"
]
Effect = "Allow"
Resource = "*"
}
]
})
}

resource "aws_iam_role" "dynamodb_role" {
name = "DavesDancingDoolittle-role"
Expand Down
33 changes: 15 additions & 18 deletions scenarios/secrets_in_the_cloud/terraform/lambda_function.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@
# - An AWS IAM Role
# - An AWS IAM Role Policy

resource "aws_cloudwatch_log_group" "lambda" {
name = "/aws/lambda/cloudgoat-secrets-lambda-${var.cgid}"
retention_in_days = 1
skip_destroy = false
}

resource "aws_lambda_function" "this" {
function_name = "cloudgoat-secrets-lambda-${var.cgid}"

filename = data.archive_file.lambda_zip.output_path
source_code_hash = data.archive_file.lambda_zip.output_base64sha256

runtime = "python3.8"
runtime = "python3.13"

role = aws_iam_role.lambda_execution.arn
role = aws_iam_role.lambda_execution.arn
handler = "lambda_function.lambda_handler"

logging_config {
log_format = "JSON"
log_group = aws_cloudwatch_log_group.lambda.name
}

environment {
variables = {
API_KEY = "DavidsDelightfulDonuts2023"
Expand All @@ -39,33 +50,19 @@ resource "aws_iam_role" "lambda_execution" {
}

resource "aws_iam_role_policy" "lambda_policy" {
name = "lambda_policy-${var.cgid}"
name = "lambda-policy-${var.cgid}"
role = aws_iam_role.lambda_execution.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Effect = "Allow"
Resource = "*"
},
{
Action = [
"rds:Describe*",
"rds:ListTagsForResource"
]
Effect = "Allow"
Resource = "*"
},
{
Action = "secretsmanager:GetSecretValue"
Effect = "Allow"
Resource = aws_secretsmanager_secret.this.arn
Resource = "${aws_cloudwatch_log_group.lambda.arn}:log-stream:*"
}
]
})
Expand Down
6 changes: 6 additions & 0 deletions scenarios/secrets_in_the_cloud/terraform/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
locals {
# Ensure the suffix doesn't contain invalid characters
# Resources names can consist only of lowercase letters, numbers, dots (.), and hyphens (-).
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
cgid_suffix = replace(var.cgid, "/[^a-z0-9-.]/", "-")
}
6 changes: 3 additions & 3 deletions scenarios/secrets_in_the_cloud/terraform/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
# - A Low-Privilege Secret Key

output "low_priv_access_key" {
value = aws_iam_access_key.low_priv_user_key.id
value = aws_iam_access_key.low_priv_user_key.id
description = "Access key ID for the low privilege IAM user."
}

output "low_priv_secret_key" {
value = aws_iam_access_key.low_priv_user_key.secret
value = aws_iam_access_key.low_priv_user_key.secret
description = "Secret access key for the low privilege IAM user."
sensitive = true
sensitive = true
}
Loading