mirror of
https://github.com/Sea-Haven-Industries/afterhours-shift-manager.git
synced 2026-09-30 07:53:11 +00:00
Prod is already a human GitHub Release. Remove the SAM tagging path so CHANGELOG.md stays App Home copy and leftover notifier IAM is destroyed on the next apply.
178 lines
6.6 KiB
Python
178 lines
6.6 KiB
Python
"""Contracts for the HCP Terraform seam (PLAT-74 / PLAT-216)."""
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
TERRAFORM = ROOT / "terraform"
|
|
LAMBDA_TF = (TERRAFORM / "lambda.tf").read_text()
|
|
HCP_IAM = (TERRAFORM / "hcp_iam.tf").read_text()
|
|
CI = (ROOT / ".github" / "workflows" / "ci.yaml").read_text()
|
|
LOCALS = (TERRAFORM / "locals.tf").read_text()
|
|
VARIABLES = (TERRAFORM / "variables.tf").read_text()
|
|
|
|
|
|
def test_sam_template_removed():
|
|
assert not (ROOT / "template.yaml").exists()
|
|
assert not (ROOT / "samconfig.toml.example").exists()
|
|
|
|
|
|
def test_zip_cd_removed():
|
|
assert not (ROOT / ".github" / "workflows" / "deploy.yaml").exists()
|
|
assert 'resource "aws_lambda_function"' not in LAMBDA_TF
|
|
assert not (TERRAFORM / "apigateway.tf").exists()
|
|
assert not (TERRAFORM / "events.tf").exists()
|
|
|
|
|
|
def test_schedules_disabled_by_default():
|
|
chunk = (
|
|
(TERRAFORM / "variables.tf")
|
|
.read_text()
|
|
.split('variable "schedules_enabled"')[1]
|
|
)
|
|
chunk = chunk.split("variable ")[0]
|
|
assert "default = false" in chunk or "default = false" in chunk
|
|
|
|
|
|
def test_ecs_schedules_disabled_by_default():
|
|
chunk = (
|
|
(TERRAFORM / "variables.tf")
|
|
.read_text()
|
|
.split('variable "ecs_schedules_enabled"')[1]
|
|
)
|
|
chunk = chunk.split("variable ")[0]
|
|
assert "default = false" in chunk or "default = false" in chunk
|
|
|
|
|
|
def test_workspaces_use_app_tag():
|
|
versions = (TERRAFORM / "versions.tf").read_text()
|
|
assert 'tags = ["app:afterhours-shift-manager"]' in versions
|
|
assert 'name = "afterhours-shift-manager-prod"' not in versions
|
|
assert 'hcp_workspace = "${local.project}-${var.environment}"' in LOCALS
|
|
assert "seahaven-${var.environment}" in LOCALS
|
|
|
|
|
|
def test_ecs_ignore_changes_and_task_size():
|
|
ecs = (TERRAFORM / "ecs.tf").read_text()
|
|
assert "ignore_changes = [container_definitions]" in ecs
|
|
assert "ignore_changes = [task_definition, desired_count]" in ecs
|
|
assert 'cpu = "512"' in ecs
|
|
assert 'memory = "1024"' in ecs
|
|
assert 'cpu_architecture = "ARM64"' in ecs
|
|
assert 'path = "/api/health"' in ecs
|
|
|
|
|
|
def test_stack_owns_a_vpc_instead_of_looking_up_default():
|
|
vpc = (TERRAFORM / "vpc.tf").read_text()
|
|
ecs = (TERRAFORM / "ecs.tf").read_text()
|
|
assert 'resource "aws_vpc" "this"' in vpc
|
|
assert "cidr_block = local.vpc_cidr" in vpc
|
|
assert 'vpc_cidr = "10.70.0.0/16"' in LOCALS
|
|
assert 'data "aws_vpc" "default"' not in ecs
|
|
assert "data.aws_vpc.default" not in ecs
|
|
assert "data.aws_subnets.default" not in ecs
|
|
assert "aws_vpc.this.id" in ecs
|
|
assert "aws_subnet.public[*].id" in ecs
|
|
assert "ec2:CreateVpc" in HCP_IAM
|
|
assert "sid = \"RefreshVpc\"" in HCP_IAM
|
|
assert "afterhours-shift-manager-ecs" in HCP_IAM
|
|
assert "hcptf_apply_ecs" in HCP_IAM
|
|
assert 'resource "aws_iam_policy" "hcptf_apply_ecs"' in HCP_IAM
|
|
assert 'resource "aws_iam_role_policy" "hcptf_apply_ecs"' not in HCP_IAM
|
|
assert "aws_iam_policy.hcptf_apply_ecs.arn" in HCP_IAM
|
|
assert "sid = \"CreateElbAndEcsServiceLinkedRoles\"" in HCP_IAM
|
|
assert "iam:CreateServiceLinkedRole" in HCP_IAM
|
|
|
|
|
|
def test_ecs_task_boundary_uses_static_arns():
|
|
iam = (TERRAFORM / "iam.tf").read_text()
|
|
chunk = iam.split('data "aws_iam_policy_document" "ecs_task_boundary"')[1]
|
|
chunk = chunk.split("resource ")[0]
|
|
assert "aws_dynamodb_table.shifts" not in chunk
|
|
assert "aws_sqs_queue.jobs" not in chunk
|
|
assert "aws_ecr_repository.api" not in chunk
|
|
assert "aws_cloudwatch_log_group.api" not in chunk
|
|
assert "table/${local.table_name}" in chunk
|
|
assert "log-group:/ecs/${local.project}" in chunk
|
|
|
|
|
|
def test_deploy_api_workflow_exists():
|
|
deploy_api = (ROOT / ".github" / "workflows" / "deploy-api.yaml").read_text()
|
|
assert "environment: ${{ needs.target.outputs.environment }}" in deploy_api
|
|
assert "/afterhours-shift-manager/deploy/cluster" in deploy_api
|
|
assert "linux/arm64" in deploy_api
|
|
assert "gh release create" in deploy_api
|
|
|
|
|
|
def test_in_repo_hcptf_roles():
|
|
assert 'apply_role = "hcptf-afterhours-shift-manager"' in LOCALS
|
|
assert 'plan_role = "hcptf-afterhours-shift-manager-plan"' in LOCALS
|
|
assert "hcptf_apply" in HCP_IAM
|
|
assert "DenyCreatePolicy" in HCP_IAM
|
|
|
|
|
|
def test_ci_runs_pytest_and_terraform_validate():
|
|
assert "ci-python-sam" not in CI
|
|
assert "pytest" in CI
|
|
assert "terraform fmt -check" in CI
|
|
assert "terraform init -backend=false" in CI
|
|
assert "terraform validate" in CI
|
|
|
|
|
|
def test_checkcomponents_queue_arn_variable_matches_iam_references():
|
|
assert 'variable "checkcomponents_queue_arn"' in VARIABLES
|
|
assert "var.checkcomponents_queue_arn" in LAMBDA_TF
|
|
boundary = (TERRAFORM / "lambda_boundary.tf").read_text()
|
|
assert "var.checkcomponents_queue_arn" in boundary
|
|
data_tf = (TERRAFORM / "data.tf").read_text()
|
|
assert "dev_has_no_paychex" in data_tf
|
|
assert "checkcomponents_pair" in data_tf
|
|
|
|
|
|
def test_seven_function_names_still_on_leftover_roles():
|
|
for name in (
|
|
"afterhours-shift-manager",
|
|
"afterhours-weekly-post",
|
|
"afterhours-roster-sync",
|
|
"afterhours-roster-api",
|
|
"afterhours-ring-scheduler",
|
|
"afterhours-holiday-router",
|
|
"afterhours-portal-api",
|
|
):
|
|
assert name in LOCALS
|
|
assert "afterhours-release-notifier" not in LOCALS
|
|
|
|
|
|
def test_weekly_post_role_is_tf_managed_name():
|
|
assert 'role_name = "afterhours-shift-manager-weekly-post"' in LOCALS
|
|
|
|
|
|
def test_github_deploy_trust_covers_image_only():
|
|
iam = (TERRAFORM / "iam_github_deploy.tf").read_text()
|
|
assert "environment:prod" in iam or "environment:prod" in LOCALS
|
|
assert "environment:dev" in iam or "environment:dev" in LOCALS
|
|
assert "deploy.yaml@" not in iam
|
|
assert "deploy-api.yaml@refs/heads/${var.github_deploy_branch}" in iam
|
|
assert "deploy-api.yaml@refs/tags/v*" in iam
|
|
assert "ecs:ListTasks" in iam
|
|
|
|
|
|
def test_plan_refresh_includes_provider6_s3_gets():
|
|
assert "s3:GetLifecycleConfiguration" in HCP_IAM
|
|
assert "s3:GetReplicationConfiguration" in HCP_IAM
|
|
assert "s3:GetBucketReplication" in HCP_IAM
|
|
|
|
|
|
def test_origins_use_fargate_url():
|
|
outputs = (TERRAFORM / "outputs.tf").read_text()
|
|
assert "aws_apigatewayv2_api.http" not in outputs
|
|
assert '${local.api_url}/slack/events' in outputs
|
|
assert "value = local.api_url" in outputs
|
|
|
|
|
|
def test_alb_alarms_remain():
|
|
alarms = (TERRAFORM / "alarms.tf").read_text()
|
|
assert "ALB-5xx-" in alarms
|
|
assert "ALB-Latency-" in alarms
|
|
assert "ALB-UnhealthyHost-" in alarms
|
|
assert "ApiGateway-" not in alarms
|
|
assert "Lambda-" not in alarms
|