Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c56629e
feat(lab01): Add initial S3 bucket
dev3kterraformer Apr 8, 2025
63d2d99
one more time
dev3kterraformer Apr 8, 2025
5285f20
feat(lab01): Add initial S3 bucket 3rd try
dev3kterraformer Apr 8, 2025
a7b0425
feat(lab01): Add initial S3 bucket 4rd try
dev3kterraformer Apr 8, 2025
38edaad
feat(lab01): Add initial S3 bucket
dev3kterraformer Apr 8, 2025
31fbc9d
feat(lab01): Add initial S3 bucket a
dev3kterraformer Apr 8, 2025
94e5120
added s3
dev3kterraformer Apr 8, 2025
e331c28
added s3 mod1
dev3kterraformer Apr 8, 2025
5600526
reset to zero
dev3kterraformer Apr 8, 2025
6a43e10
feat(lab01): Add initial S3 bucket
dev3kterraformer Apr 8, 2025
8a4fec2
feat(lab04/module): Add initial sqs-secure module code and tests
dev3kterraformer Apr 9, 2025
3658cb6
ci: Add GitHub Actions workflow for module checks
dev3kterraformer Apr 9, 2025
1ab548b
ci: Add GitHub Actions workflow for module checks 2
dev3kterraformer Apr 9, 2025
2bb5d00
feat(lab04/module): Add initial sqs-secure module code and tests
dev3kterraformer Apr 9, 2025
f6be6a4
ci: Add GitHub Actions workflow for module checks
dev3kterraformer Apr 9, 2025
53d4674
ci: try2
dev3kterraformer Apr 9, 2025
2bc78ba
ci: Add GitHub Actions workflow for module checks 33
dev3kterraformer Apr 9, 2025
bed71f1
ci: Add GitHub Actions workflow for module checks 333
dev3kterraformer Apr 9, 2025
ab0796f
ci: Skip CKV2_AWS_64 check for lab purposes
dev3kterraformer Apr 9, 2025
562e573
feat(lab05): Configure dev and prod SQS environments
dev3kterraformer Apr 9, 2025
25291aa
feat: Add Purpose tag to dev SQS queue
dev3kterraformer Apr 9, 2025
b60514a
feat: Add ONE MORE tag to dev SQS queue
dev3kterraformer Apr 9, 2025
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
64 changes: 64 additions & 0 deletions .github/workflows/module-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Module CI Checks (Lab 4)

on:
# Run on pushes to main branch
push:
branches:
- main
# Run on pull requests targeting main branch
pull_request:
branches:
- main
# Allows manual triggering from GitHub UI
workflow_dispatch:

jobs:
test:
name: Lint, Validate, Test, Scan
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
# with:
# terraform_version: "1.7.x" # Optional: Pin version

- name: Terraform Format Check (Recursive)
working-directory: ./lab04 # Run from lab04 dir
run: terraform fmt -check -recursive

- name: Terraform Init (for Root Validate)
working-directory: ./lab04 # Run from lab04 dir
run: terraform init # Needed for validate

- name: Terraform Validate (Root Harness)
working-directory: ./lab04 # Run from lab04 dir
run: terraform validate # Checks if lab04/main.tf is valid

- name: Init Module for Testing
working-directory: ./lab04/modules/sqs-secure # Go into module dir
env: # Add AWS credentials and region for test apply steps
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-west-2"
run: terraform init # Initialize providers needed for tests

- name: Terraform Test Module
working-directory: ./lab04/modules/sqs-secure # Run test from module dir
env: # Add AWS credentials and region for test apply steps
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-west-2"
run: terraform test # Runs tests found in ./tests/

- name: Install Checkov
# Run pip install globally or in a virtual env
run: pip install checkov

- name: Run Checkov Scan
working-directory: ./lab04 # Define where checkov runs FROM
# Point checkov specifically to the module directory
run: checkov -d ./modules/sqs-secure --quiet --skip-check CKV2_AWS_64
32 changes: 32 additions & 0 deletions lab01/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0" // Use an appropriate AWS provider version
}
random = {
source = "hashicorp/random"
version = "~> 3.1"
}
}

# Backend is configured implicitly by HCP Terraform Workspace
}

provider "aws" {
region = "us-west-2" // Ensure correct region
}

resource "random_string" "suffix" {
length = 8
special = false
upper = false
}

resource "aws_s3_bucket" "learning_bucket" {
bucket = "tf-adv-lab01-${random_string.suffix.result}" # Construct unique name

tags = {
Name = "TF Advanced Lab 1 Bucket"
}
}
4 changes: 2 additions & 2 deletions lab04/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ terraform {
source = "hashicorp/aws"
version = "~> 5.0"
}
# Random provider needed by module via S3 bucket name
# Random provider needed by module via S3 bucket name
random = {
source = "hashicorp/random"
source = "hashicorp/random"
version = "~> 3.1"
}
}
Expand Down
4 changes: 2 additions & 2 deletions lab04/modules/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ terraform {
source = "hashicorp/aws"
version = "~> 5.0"
}
# Random provider needed by module via S3 bucket name
# Random provider needed by module via S3 bucket name
random = {
source = "hashicorp/random"
source = "hashicorp/random"
version = "~> 3.1"
}
}
Expand Down
4 changes: 2 additions & 2 deletions lab04/modules/sqs-secure/main.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
resource "aws_kms_key" "sqs_key" {
description = "KMS key for encrypting ${var.queue_name_prefix} SQS queues"
description = "KMS key for encrypting ${var.queue_name_prefix} SQS queues"
enable_key_rotation = true
tags = var.tags
tags = var.tags
}

resource "aws_sqs_queue" "dlq" {
Expand Down
2 changes: 1 addition & 1 deletion lab04/modules/sqs-secure/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ output "main_queue_url" {
output "dlq_arn" {
description = "The ARN of the Dead Letter Queue (DLQ), if created."
# Use try() to gracefully return null if the DLQ doesn't exist (count=0)
value = try(aws_sqs_queue.dlq[0].arn, null)
value = try(aws_sqs_queue.dlq[0].arn, null)
}

output "kms_key_arn" {
Expand Down
110 changes: 44 additions & 66 deletions lab04/modules/sqs-secure/tests/sqs_secure_test.tftest.hcl
Original file line number Diff line number Diff line change
@@ -1,96 +1,74 @@
variables {
queue_name_prefix = "lab3-test-defaults"
queue_name_prefix = "lab03-test-defaults"
# enable_dlq defaults to true in the module
# tags defaults to {} in the module
}

# Simple test to ensure plan works properly
run "plan_default_settings" {
# command = plan is the default, so it's optional here

check "plan_produces_changes" {
assert {
# Verify that the plan is not empty
condition = length(resource_changes) > 0
error_message = "Plan should propose at least one resource change with default settings."
}
}
command = plan
# No assert needed; success means plan executes without errors
}

# Test to ensure ARNs are being assigned correctly
run "apply_and_check_outputs" {
command = apply

check "outputs_are_valid" {
assert {
condition = output.main_queue_arn != null && substr(output.main_queue_arn, 0, 12) == "arn:aws:sqs:"
error_message = "Main queue ARN should be a valid SQS ARN."
}
assert {
condition = output.kms_key_arn != null && substr(output.kms_key_arn, 0, 12) == "arn:aws:kms:"
error_message = "KMS key ARN should be a valid KMS ARN."
}
assert {
# DLQ is enabled by default, so its ARN should be present
condition = output.dlq_arn != null && substr(output.dlq_arn, 0, 12) == "arn:aws:sqs:"
error_message = "DLQ ARN should be a valid SQS ARN when DLQ is enabled."
}
# Could also add checks for main_queue_url format if needed
assert {
condition = output.main_queue_arn != null && substr(output.main_queue_arn, 0, 12) == "arn:aws:sqs:"
error_message = "Main queue ARN should be a valid SQS ARN."
}
assert {
condition = output.kms_key_arn != null && substr(output.kms_key_arn, 0, 12) == "arn:aws:kms:"
error_message = "KMS key ARN should be a valid KMS ARN."
}
assert {
# DLQ is enabled by default, so its ARN should be present
condition = output.dlq_arn != null && substr(output.dlq_arn, 0, 12) == "arn:aws:sqs:"
error_message = "DLQ ARN should be a valid SQS ARN when DLQ is enabled."
}
# Could also add checks for main_queue_url format if needed

}

run "plan_dlq_disabled" {
# Test to ensure DLQ is not created when enable_dlq is false
run "apply_dlq_disabled" {
command = apply
# Override variables specifically for this run
variables {
queue_name_prefix = "lab3-test-no-dlq"
queue_name_prefix = "lab03-test-no-dlq"
enable_dlq = false # Disable the DLQ for this test case
}

check "plan_creates_correct_resources" {
assert {
# Check that the DLQ resource change is absent
condition = !anytrue([for rc in resource_changes : rc.address == "module.test.aws_sqs_queue.dlq"])
# Note: The address includes 'module.test' because terraform test wraps the module under test.
error_message = "DLQ resource should not be present in the plan when enable_dlq is false."
}
assert {
# Check that the main queue and KMS key *are* present
condition = anytrue([for rc in resource_changes : rc.address == "module.test.aws_sqs_queue.main"]) && \
anytrue([for rc in resource_changes : rc.address == "module.test.aws_kms_key.sqs_key"])
error_message = "Main queue and KMS key should be present in the plan."
}
assert {
# Check that given count is zero, the list of dlq objects should be empty
condition = length(aws_sqs_queue.dlq) == 0
error_message = "DLQ should be an empty list when enable_dlq is false"
}
}

run "apply_dlq_disabled_outputs" {
command = apply

# We need to reference the variables defined in the preceding run block.
# Terraform test currently reuses the *last specified* variables block if a run block
# doesn't define its own. So, this run will correctly use enable_dlq = false.
# Be mindful of this behavior in complex tests.

check "outputs_reflect_dlq_disabled" {
assert {
condition = output.dlq_arn == null
error_message = "DLQ ARN output should be null when enable_dlq is false."
}
assert {
condition = output.main_queue_arn != null # Main queue should still exist
error_message = "Main queue ARN should still be present."
}
assert {
# Check that the output.dlq_arn is not set
condition = output.dlq_arn == null
error_message = "DLQ ARN output should be null when enable_dlq is false."
}
assert {
# Check that the main queue is still present
condition = aws_sqs_queue.main.name == "lab03-test-no-dlq"
error_message = "Main queue should be created with correct name"
}
assert {
# Check that the KMS key is still present
condition = aws_kms_key.sqs_key.arn != null
error_message = "KMS key should be created"
}
}

run "fail_on_empty_prefix" {
variables {
queue_name_prefix = "" # Invalid input
enable_dlq = false # Keep other variables consistent if needed
}
command = plan

# command = plan is default

# Expect the plan to fail with the specific validation error message
# Test succeeds if validation for queue_name_prefix errors out
expect_failures = [
var.queue_name_prefix.validation[0].error_message,
# Can reference module variable validation messages directly.
var.queue_name_prefix
]
}
48 changes: 48 additions & 0 deletions lab05/dev/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.1"
}
}
# Backend configured by HCP Workspace
}

# Variables will be populated by HCP Workspace Variables
variable "queue_prefix" {
type = string
description = "Prefix for queue names, provided by workspace."
}

variable "environment_tag" {
type = string
description = "Tag value for the Environment tag, provided by workspace."
}

provider "aws" {
region = "us-west-2"
}

module "dev_queue" {
# Replace <YOUR_ORG_NAME> with your HCP Org Name
source = "app.terraform.io/tf-advanced-labs/sqs-secure/aws"
version = "~> 1.0.0" # Use constraint matching published version

queue_name_prefix = var.queue_prefix # From workspace variable
enable_dlq = true # Keep DLQ enabled for dev

tags = {
Project = "Advanced TF Course"
Environment = var.environment_tag # From workspace variable
GitOpsManaged = "true" # <<< Added Tag
Purpose = "GitOps Demo" # <<< Added Tag
Dept = "Engineering" # One more added tag
}
}

# Optional: Define outputs if needed for cross-workspace dependencies later
# output "dev_queue_arn" { value = module.dev_queue.main_queue_arn }
45 changes: 45 additions & 0 deletions lab05/prod/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.1"
}
}
# Backend configured by HCP Workspace
}

# Variables will be populated by HCP Workspace Variables
variable "queue_prefix" {
type = string
description = "Prefix for queue names, provided by workspace."
}

variable "environment_tag" {
type = string
description = "Tag value for the Environment tag, provided by workspace."
}

provider "aws" {
region = "us-west-2"
}

module "prod_queue" {
# Replace <YOUR_ORG_NAME> with your HCP Org Name
source = "app.terraform.io/tf-advanced-labs/sqs-secure/aws"
version = "~> 1.0.0" # Use constraint matching published version

queue_name_prefix = var.queue_prefix # From workspace variable
enable_dlq = true # Keep DLQ enabled for prod

tags = {
Project = "Advanced TF Course"
Environment = var.environment_tag # From workspace variable
}
}

# Optional: Define outputs if needed
# output "prod_queue_arn" { value = module.prod_queue.main_queue_arn }