mirror of
https://github.com/ghndrx/terraform-foundation.git
synced 2026-02-10 14:54:56 +00:00
feat: Terraform Foundation - AWS Landing Zone
Enterprise-grade multi-tenant AWS cloud foundation. Modules: - GitHub OIDC for keyless CI/CD authentication - IAM account settings and security baseline - AWS Config Rules for compliance - ABAC (Attribute-Based Access Control) - SCPs (Service Control Policies) Features: - Multi-account architecture - Cost optimization patterns - Security best practices - Comprehensive documentation Tech: Terraform, AWS Organizations, IAM Identity Center
This commit is contained in:
210
terraform/modules/github-oidc/tests/basic.tftest.hcl
Normal file
210
terraform/modules/github-oidc/tests/basic.tftest.hcl
Normal file
@@ -0,0 +1,210 @@
|
||||
################################################################################
|
||||
# GitHub OIDC Module - Basic Tests
|
||||
# Uses Terraform native testing framework
|
||||
################################################################################
|
||||
|
||||
# Mock AWS provider for unit tests
|
||||
mock_provider "aws" {
|
||||
mock_data "aws_caller_identity" {
|
||||
defaults = {
|
||||
account_id = "123456789012"
|
||||
arn = "arn:aws:iam::123456789012:user/test"
|
||||
user_id = "AIDATEST123456789"
|
||||
}
|
||||
}
|
||||
|
||||
mock_data "aws_region" {
|
||||
defaults = {
|
||||
name = "us-east-1"
|
||||
}
|
||||
}
|
||||
|
||||
mock_data "aws_partition" {
|
||||
defaults = {
|
||||
partition = "aws"
|
||||
dns_suffix = "amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Basic role creation
|
||||
run "basic_role_creation" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
roles = {
|
||||
deploy = {
|
||||
repos = ["test-repo"]
|
||||
branches = ["main"]
|
||||
policy_statements = [{
|
||||
sid = "TestAccess"
|
||||
actions = ["s3:GetObject"]
|
||||
resources = ["arn:aws:s3:::test-bucket/*"]
|
||||
}]
|
||||
}
|
||||
}
|
||||
tags = {
|
||||
Environment = "test"
|
||||
}
|
||||
}
|
||||
|
||||
# Verify OIDC provider is created
|
||||
assert {
|
||||
condition = aws_iam_openid_connect_provider.github[0].url == "https://token.actions.githubusercontent.com"
|
||||
error_message = "OIDC provider URL is incorrect"
|
||||
}
|
||||
|
||||
# Verify role is created with correct name
|
||||
assert {
|
||||
condition = aws_iam_role.github["deploy"].name == "github-deploy"
|
||||
error_message = "Role name should be github-deploy"
|
||||
}
|
||||
|
||||
# Verify IAM path is set correctly
|
||||
assert {
|
||||
condition = aws_iam_role.github["deploy"].path == "/github-actions/"
|
||||
error_message = "Role path should be /github-actions/"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Repository normalization with org prefix
|
||||
run "repo_normalization" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "my-org"
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["repo-without-org"] # Should become my-org/repo-without-org
|
||||
branches = ["main"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Role should be created (validates normalization works)
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].name == "github-test"
|
||||
error_message = "Role should be created with normalized repo"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Multiple roles with different configurations
|
||||
run "multiple_roles" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
roles = {
|
||||
validate = {
|
||||
repos = ["app"]
|
||||
pull_request = true
|
||||
max_session_hours = 1
|
||||
}
|
||||
deploy = {
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
max_session_hours = 2
|
||||
}
|
||||
release = {
|
||||
repos = ["app"]
|
||||
tags = ["v*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Verify all roles are created
|
||||
assert {
|
||||
condition = length(aws_iam_role.github) == 3
|
||||
error_message = "Should create 3 roles"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Terraform deploy template role
|
||||
run "terraform_template_role" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
terraform_deploy_role = {
|
||||
enabled = true
|
||||
repos = ["infra"]
|
||||
branches = ["main"]
|
||||
state_bucket = "my-tf-state"
|
||||
dynamodb_table = "terraform-locks"
|
||||
}
|
||||
}
|
||||
|
||||
# Verify Terraform role is created
|
||||
assert {
|
||||
condition = aws_iam_role.terraform[0].name == "github-terraform"
|
||||
error_message = "Terraform role should be created"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: ECR push template role
|
||||
run "ecr_template_role" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
ecr_push_role = {
|
||||
enabled = true
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
ecr_repos = ["my-ecr-repo"]
|
||||
}
|
||||
}
|
||||
|
||||
# Verify ECR role is created
|
||||
assert {
|
||||
condition = aws_iam_role.ecr[0].name == "github-ecr-push"
|
||||
error_message = "ECR role should be created"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Session duration capping
|
||||
run "session_duration_capping" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
max_session_hours_limit = 2
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
max_session_hours = 4 # Should be capped to 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Verify session duration is capped (2 hours = 7200 seconds)
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].max_session_duration == 7200
|
||||
error_message = "Session duration should be capped at 2 hours (7200 seconds)"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Existing provider ARN (no provider creation)
|
||||
run "existing_provider" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
create_provider = false
|
||||
provider_arn = "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
|
||||
github_org = "test-org"
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Verify no provider is created
|
||||
assert {
|
||||
condition = length(aws_iam_openid_connect_provider.github) == 0
|
||||
error_message = "Should not create provider when create_provider=false"
|
||||
}
|
||||
}
|
||||
203
terraform/modules/github-oidc/tests/security.tftest.hcl
Normal file
203
terraform/modules/github-oidc/tests/security.tftest.hcl
Normal file
@@ -0,0 +1,203 @@
|
||||
################################################################################
|
||||
# GitHub OIDC Module - Security Tests
|
||||
# Validates security best practices are enforced
|
||||
################################################################################
|
||||
|
||||
mock_provider "aws" {
|
||||
mock_data "aws_caller_identity" {
|
||||
defaults = {
|
||||
account_id = "123456789012"
|
||||
}
|
||||
}
|
||||
|
||||
mock_data "aws_region" {
|
||||
defaults = {
|
||||
name = "us-east-1"
|
||||
}
|
||||
}
|
||||
|
||||
mock_data "aws_partition" {
|
||||
defaults = {
|
||||
partition = "aws"
|
||||
dns_suffix = "amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Wildcard repos denied by default
|
||||
run "wildcard_repos_denied" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
deny_wildcard_repos = true
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["*"] # Wildcard - should fail without workflow_ref
|
||||
branches = ["main"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect_failures = [
|
||||
# This should fail validation because wildcard repos require workflow_ref
|
||||
var.roles
|
||||
]
|
||||
}
|
||||
|
||||
# Test: Wildcard repos allowed with workflow_ref
|
||||
run "wildcard_repos_with_workflow_ref" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
deny_wildcard_repos = true
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["*"]
|
||||
workflow_ref = "test-org/workflows/.github/workflows/deploy.yml@main"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Should succeed because workflow_ref is specified
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].name == "github-test"
|
||||
error_message = "Should allow wildcard with workflow_ref"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: IAM path isolation
|
||||
run "iam_path_isolation" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
path = "/github-actions/"
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Verify path is set for role isolation
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].path == "/github-actions/"
|
||||
error_message = "Role should use isolated IAM path"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Permissions boundary is applied
|
||||
run "permissions_boundary_applied" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
permissions_boundary = "arn:aws:iam::123456789012:policy/TestBoundary"
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Verify permissions boundary is set
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].permissions_boundary == "arn:aws:iam::123456789012:policy/TestBoundary"
|
||||
error_message = "Permissions boundary should be applied to role"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Terraform role has explicit denies
|
||||
run "terraform_role_explicit_denies" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
terraform_deploy_role = {
|
||||
enabled = true
|
||||
repos = ["infra"]
|
||||
branches = ["main"]
|
||||
denied_actions = ["iam:CreateUser", "organizations:*"]
|
||||
}
|
||||
}
|
||||
|
||||
# Verify deny policy is created
|
||||
assert {
|
||||
condition = aws_iam_role_policy.terraform_deny[0].name == "terraform-deny"
|
||||
error_message = "Terraform deny policy should be created"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: ECR role requires explicit repos
|
||||
run "ecr_explicit_repos_required" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
ecr_push_role = {
|
||||
enabled = true
|
||||
repos = ["app"]
|
||||
ecr_repos = ["my-ecr-repo"] # Explicit ECR repo required
|
||||
}
|
||||
}
|
||||
|
||||
# Should succeed with explicit ECR repos
|
||||
assert {
|
||||
condition = aws_iam_role.ecr[0].name == "github-ecr-push"
|
||||
error_message = "ECR role should be created with explicit repos"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Role tags include security metadata
|
||||
run "security_tags" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["app"]
|
||||
branches = ["main"]
|
||||
}
|
||||
}
|
||||
tags = {
|
||||
Environment = "production"
|
||||
}
|
||||
}
|
||||
|
||||
# Verify tags include ManagedBy and Module
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].tags["ManagedBy"] == "terraform"
|
||||
error_message = "Role should have ManagedBy tag"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].tags["Module"] == "github-oidc"
|
||||
error_message = "Role should have Module tag"
|
||||
}
|
||||
}
|
||||
|
||||
# Test: Trust policy uses StringLike for subject claims
|
||||
run "trust_policy_string_like" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
github_org = "test-org"
|
||||
roles = {
|
||||
test = {
|
||||
repos = ["app"]
|
||||
branches = ["main", "develop"] # Multiple branches
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Role should be created with proper trust policy
|
||||
assert {
|
||||
condition = aws_iam_role.github["test"].assume_role_policy != ""
|
||||
error_message = "Trust policy should be set"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user