mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 05:23:13 +00:00
ci: convert onto org HCP reusables (PLAT-222) (#214)
* ci: convert onto org HCP reusables Switch Fargate CD and CI to the v1.0.13 org workflows, emit ci-complete, and retarget githubdeploy OIDC to the reusable plus the thin caller. * chore(security): retarget githubdeploy Checkov suppression The OIDC dual-claim edit shifted CKV_AWS_111 from line 40 to 49. Permissions are unchanged. * style: apply formatter * ci: pin org reusables to v1.0.14 Drop collect-only and requirements from the python lint caller now that ci-python-app is lint-only. * test(ci): probe autofix with a ruff format violation * style: apply formatter --------- Co-authored-by: sea-haven-auto-fix[bot] <5037331+sea-haven-auto-fix[bot]@users.noreply.github.com>
This commit is contained in:
parent
7574fc471a
commit
f632020b20
8 changed files with 129 additions and 239 deletions
32
.github/workflows/ci-terraform.yaml
vendored
32
.github/workflows/ci-terraform.yaml
vendored
|
|
@ -1,32 +0,0 @@
|
||||||
name: Terraform CI
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- "terraform/**"
|
|
||||||
- ".github/workflows/ci-terraform.yaml"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
terraform:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: terraform
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
||||||
|
|
||||||
- uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
|
|
||||||
with:
|
|
||||||
terraform_version: "1.9.8"
|
|
||||||
|
|
||||||
- name: Terraform fmt
|
|
||||||
run: terraform fmt -check -recursive
|
|
||||||
|
|
||||||
- name: Terraform init
|
|
||||||
run: terraform init -backend=false
|
|
||||||
|
|
||||||
- name: Terraform validate
|
|
||||||
run: terraform validate
|
|
||||||
55
.github/workflows/ci.yml
vendored
55
.github/workflows/ci.yml
vendored
|
|
@ -1,21 +1,37 @@
|
||||||
name: CI
|
name: CI
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main, hotfix/**, release/**]
|
||||||
merge_group:
|
merge_group:
|
||||||
|
push:
|
||||||
|
branches: [hotfix/**, release/**]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
autofix:
|
||||||
uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-app.yaml@9781774f04b824b1182ff41638687f1c01c04361 # v1.0.11
|
if: github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork
|
||||||
|
uses: Sea-Haven-Industries/.github/.github/workflows/ci-autofix.yaml@fd4113241058d4709f80d5c29f7d5c43030ae6fa # v1.0.14
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
format-command: ruff format .
|
||||||
|
lint-fix-command: ruff check --fix .
|
||||||
|
extra-command: terraform fmt -recursive terraform
|
||||||
|
terraform-version: "1.9.8"
|
||||||
|
|
||||||
|
lint:
|
||||||
|
needs: autofix
|
||||||
|
if: always() && !cancelled() && (needs.autofix.result == 'skipped' || needs.autofix.outputs.committed != 'true')
|
||||||
|
uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-app.yaml@fd4113241058d4709f80d5c29f7d5c43030ae6fa # v1.0.14
|
||||||
with:
|
with:
|
||||||
python-version: "3.12.14"
|
python-version: "3.12.14"
|
||||||
requirements: "requirements-api.txt"
|
|
||||||
collect-only: false
|
|
||||||
|
|
||||||
template-js:
|
template-js:
|
||||||
|
needs: autofix
|
||||||
|
if: always() && !cancelled() && (needs.autofix.result == 'skipped' || needs.autofix.outputs.committed != 'true')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -38,6 +54,8 @@ jobs:
|
||||||
run: npm run openapi:lint
|
run: npm run openapi:lint
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
needs: autofix
|
||||||
|
if: always() && !cancelled() && (needs.autofix.result == 'skipped' || needs.autofix.outputs.committed != 'true')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -63,3 +81,30 @@ jobs:
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: pytest
|
run: pytest
|
||||||
|
|
||||||
|
terraform:
|
||||||
|
needs: autofix
|
||||||
|
if: always() && !cancelled() && (needs.autofix.result == 'skipped' || needs.autofix.outputs.committed != 'true')
|
||||||
|
uses: Sea-Haven-Industries/.github/.github/workflows/ci-terraform.yaml@fd4113241058d4709f80d5c29f7d5c43030ae6fa # v1.0.14
|
||||||
|
with:
|
||||||
|
terraform-version: "1.9.8"
|
||||||
|
|
||||||
|
ci-complete:
|
||||||
|
name: ci-complete
|
||||||
|
needs: [autofix, lint, template-js, test, terraform]
|
||||||
|
if: always() && !cancelled() && (needs.autofix.result == 'skipped' || needs.autofix.outputs.committed != 'true')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- name: Require portions
|
||||||
|
env:
|
||||||
|
LINT: ${{ needs.lint.result }}
|
||||||
|
TEMPLATE_JS: ${{ needs.template-js.result }}
|
||||||
|
TEST: ${{ needs.test.result }}
|
||||||
|
TERRAFORM: ${{ needs.terraform.result }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
test "${LINT}" = success
|
||||||
|
test "${TEMPLATE_JS}" = success
|
||||||
|
test "${TEST}" = success
|
||||||
|
test "${TERRAFORM}" = success
|
||||||
|
|
|
||||||
225
.github/workflows/deploy-api.yaml
vendored
225
.github/workflows/deploy-api.yaml
vendored
|
|
@ -1,8 +1,8 @@
|
||||||
name: Deploy API
|
name: Deploy API
|
||||||
|
|
||||||
# Fargate image CD (PLAT-215). GitHub Actions builds the Flask image, pushes
|
# Fargate image CD. GitHub Actions builds the Flask image, pushes to ECR,
|
||||||
# to ECR, and registers a new task definition. Terraform owns the cluster,
|
# and registers a new task definition. Terraform owns the cluster, service,
|
||||||
# service, ALB, and ignores container_definitions / task_definition.
|
# ALB, and ignores container_definitions / task_definition.
|
||||||
#
|
#
|
||||||
# push to main -> dev, at github.sha
|
# push to main -> dev, at github.sha
|
||||||
# release: published -> prod, at the release tag
|
# release: published -> prod, at the release tag
|
||||||
|
|
@ -20,7 +20,6 @@ on:
|
||||||
- "*.md"
|
- "*.md"
|
||||||
- ".github/workflows/weekly-menu.yml"
|
- ".github/workflows/weekly-menu.yml"
|
||||||
- ".github/workflows/ci.yml"
|
- ".github/workflows/ci.yml"
|
||||||
- ".github/workflows/ci-terraform.yaml"
|
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
@ -40,199 +39,33 @@ permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
target:
|
deploy-dev:
|
||||||
name: Resolve target
|
name: Deploy API to dev
|
||||||
runs-on: ubuntu-latest
|
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'dev')
|
||||||
timeout-minutes: 5
|
uses: Sea-Haven-Industries/.github/.github/workflows/cd-hcp-fargate.yaml@fd4113241058d4709f80d5c29f7d5c43030ae6fa # v1.0.14
|
||||||
outputs:
|
|
||||||
environment: ${{ steps.resolve.outputs.environment }}
|
|
||||||
ref: ${{ steps.resolve.outputs.ref }}
|
|
||||||
steps:
|
|
||||||
- id: resolve
|
|
||||||
env:
|
|
||||||
EVENT_NAME: ${{ github.event_name }}
|
|
||||||
GITHUB_REF_NAME_IN: ${{ github.ref }}
|
|
||||||
GITHUB_SHA_IN: ${{ github.sha }}
|
|
||||||
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
||||||
REPO: ${{ github.repository }}
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
INPUT_ENVIRONMENT: ${{ inputs.environment }}
|
|
||||||
INPUT_REF: ${{ inputs.ref }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
case "${EVENT_NAME}" in
|
|
||||||
push)
|
|
||||||
if [ "${GITHUB_REF_NAME_IN}" != "refs/heads/main" ]; then
|
|
||||||
echo "push deploys only run from main" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
environment=dev
|
|
||||||
ref="${GITHUB_SHA_IN}"
|
|
||||||
;;
|
|
||||||
release)
|
|
||||||
environment=prod
|
|
||||||
ref="${RELEASE_TAG}"
|
|
||||||
status="$(gh api "repos/${REPO}/compare/main...${RELEASE_TAG}" --jq .status)"
|
|
||||||
if [ "${status}" != "behind" ] && [ "${status}" != "identical" ]; then
|
|
||||||
echo "release tag ${RELEASE_TAG} is not on main (compare status: ${status})" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
workflow_dispatch)
|
|
||||||
environment="${INPUT_ENVIRONMENT}"
|
|
||||||
ref="${INPUT_REF:-${GITHUB_SHA_IN}}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "unsupported event ${EVENT_NAME}" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
{
|
|
||||||
echo "environment=${environment}"
|
|
||||||
echo "ref=${ref}"
|
|
||||||
} >> "${GITHUB_OUTPUT}"
|
|
||||||
echo "Deploying ${ref} to ${environment}"
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
name: Deploy API to ${{ needs.target.outputs.environment }}
|
|
||||||
needs: target
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 30
|
|
||||||
environment: ${{ needs.target.outputs.environment }}
|
|
||||||
concurrency:
|
|
||||||
group: deploy-api-${{ needs.target.outputs.environment }}
|
|
||||||
cancel-in-progress: false
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
id-token: write
|
id-token: write
|
||||||
env:
|
secrets: inherit
|
||||||
AWS_REGION: us-east-1
|
with:
|
||||||
DEPLOY_ROLE_ARN: ${{ vars.DEPLOY_ROLE_ARN }}
|
environment: dev
|
||||||
steps:
|
ref: ${{ inputs.ref }}
|
||||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
ssm-prefix: /meal-order-manager/deploy
|
||||||
with:
|
docker-platform: linux/amd64
|
||||||
ref: ${{ needs.target.outputs.ref }}
|
extra-task-env: '{"SENTRY_DSN_PARAM":"/meal-order-manager/sentry-dsn"}'
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Resolve commit
|
deploy-prod:
|
||||||
id: commit
|
name: Deploy API to prod
|
||||||
run: |
|
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'prod')
|
||||||
set -euo pipefail
|
uses: Sea-Haven-Industries/.github/.github/workflows/cd-hcp-fargate.yaml@fd4113241058d4709f80d5c29f7d5c43030ae6fa # v1.0.14
|
||||||
sha="$(git rev-parse HEAD)"
|
permissions:
|
||||||
echo "sha=${sha}" >> "${GITHUB_OUTPUT}"
|
contents: read
|
||||||
echo "Building ${sha}"
|
id-token: write
|
||||||
|
secrets: inherit
|
||||||
- name: Configure AWS credentials using OIDC
|
with:
|
||||||
uses: aws-actions/configure-aws-credentials@e1253824e5c10ff9df46874f81ed3ec929e19cfd # v6.3.0
|
environment: prod
|
||||||
with:
|
ref: ${{ github.event.release.tag_name || inputs.ref }}
|
||||||
role-to-assume: ${{ env.DEPLOY_ROLE_ARN }}
|
ssm-prefix: /meal-order-manager/deploy
|
||||||
aws-region: us-east-1
|
docker-platform: linux/amd64
|
||||||
audience: sts.amazonaws.com
|
ship-gate: true
|
||||||
|
extra-task-env: '{"SENTRY_DSN_PARAM":"/meal-order-manager/sentry-dsn"}'
|
||||||
- name: Get deploy parameters
|
|
||||||
id: deploy
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
get_param() {
|
|
||||||
aws ssm get-parameter --name "$1" --query Parameter.Value --output text
|
|
||||||
}
|
|
||||||
CLUSTER=$(get_param /meal-order-manager/deploy/cluster)
|
|
||||||
SERVICE=$(get_param /meal-order-manager/deploy/service)
|
|
||||||
FAMILY=$(get_param /meal-order-manager/deploy/task-family)
|
|
||||||
ECR=$(get_param /meal-order-manager/deploy/ecr-repository)
|
|
||||||
CONTAINER=$(get_param /meal-order-manager/deploy/container-name)
|
|
||||||
API_URL=$(get_param /meal-order-manager/deploy/api-url)
|
|
||||||
{
|
|
||||||
echo "cluster=${CLUSTER}"
|
|
||||||
echo "service=${SERVICE}"
|
|
||||||
echo "family=${FAMILY}"
|
|
||||||
echo "ecr=${ECR}"
|
|
||||||
echo "container=${CONTAINER}"
|
|
||||||
echo "api_url=${API_URL}"
|
|
||||||
} >> "${GITHUB_OUTPUT}"
|
|
||||||
|
|
||||||
- name: Login to Amazon ECR
|
|
||||||
uses: aws-actions/amazon-ecr-login@03f1aad4c6c7ffd436567f42f9384779290529bd # v2.1.7
|
|
||||||
|
|
||||||
- name: Build and push image
|
|
||||||
env:
|
|
||||||
ECR: ${{ steps.deploy.outputs.ecr }}
|
|
||||||
GIT_SHA: ${{ steps.commit.outputs.sha }}
|
|
||||||
ENVIRONMENT: ${{ needs.target.outputs.environment }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
docker build \
|
|
||||||
--build-arg "GIT_SHA=${GIT_SHA}" \
|
|
||||||
-t "${ECR}:${GIT_SHA}" \
|
|
||||||
-t "${ECR}:${ENVIRONMENT}" \
|
|
||||||
.
|
|
||||||
docker push "${ECR}:${GIT_SHA}"
|
|
||||||
docker push "${ECR}:${ENVIRONMENT}"
|
|
||||||
|
|
||||||
- name: Register task definition and update service
|
|
||||||
env:
|
|
||||||
CLUSTER: ${{ steps.deploy.outputs.cluster }}
|
|
||||||
SERVICE: ${{ steps.deploy.outputs.service }}
|
|
||||||
FAMILY: ${{ steps.deploy.outputs.family }}
|
|
||||||
CONTAINER: ${{ steps.deploy.outputs.container }}
|
|
||||||
IMAGE: ${{ steps.deploy.outputs.ecr }}:${{ steps.commit.outputs.sha }}
|
|
||||||
GIT_SHA: ${{ steps.commit.outputs.sha }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
aws ecs describe-task-definition \
|
|
||||||
--task-definition "${FAMILY}" \
|
|
||||||
--query taskDefinition \
|
|
||||||
--output json \
|
|
||||||
| python3 -c '
|
|
||||||
import json, os, sys
|
|
||||||
td = json.load(sys.stdin)
|
|
||||||
for key in (
|
|
||||||
"taskDefinitionArn",
|
|
||||||
"revision",
|
|
||||||
"status",
|
|
||||||
"requiresAttributes",
|
|
||||||
"compatibilities",
|
|
||||||
"registeredAt",
|
|
||||||
"registeredBy",
|
|
||||||
"deregisteredAt",
|
|
||||||
):
|
|
||||||
td.pop(key, None)
|
|
||||||
image = os.environ["IMAGE"]
|
|
||||||
sha = os.environ["GIT_SHA"]
|
|
||||||
name = os.environ["CONTAINER"]
|
|
||||||
for container in td["containerDefinitions"]:
|
|
||||||
if container["name"] != name:
|
|
||||||
continue
|
|
||||||
container["image"] = image
|
|
||||||
env = {item["name"]: item["value"] for item in container.get("environment", [])}
|
|
||||||
env["GIT_SHA"] = sha
|
|
||||||
env["SENTRY_DSN_PARAM"] = "/meal-order-manager/sentry-dsn"
|
|
||||||
container["environment"] = [{"name": key, "value": value} for key, value in env.items()]
|
|
||||||
container.pop("command", None)
|
|
||||||
json.dump(td, sys.stdout)
|
|
||||||
' > /tmp/task-def.json
|
|
||||||
REV="$(aws ecs register-task-definition --cli-input-json file:///tmp/task-def.json --query taskDefinition.revision --output text)"
|
|
||||||
aws ecs update-service \
|
|
||||||
--cluster "${CLUSTER}" \
|
|
||||||
--service "${SERVICE}" \
|
|
||||||
--task-definition "${FAMILY}:${REV}" \
|
|
||||||
--force-new-deployment \
|
|
||||||
>/dev/null
|
|
||||||
aws ecs wait services-stable --cluster "${CLUSTER}" --services "${SERVICE}"
|
|
||||||
|
|
||||||
- name: Verify health SHA
|
|
||||||
env:
|
|
||||||
API_URL: ${{ steps.deploy.outputs.api_url }}
|
|
||||||
EXPECTED_SHA: ${{ steps.commit.outputs.sha }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
for _ in 1 2 3 4 5 6; do
|
|
||||||
BODY="$(curl -fsS "${API_URL}/api/health" || true)"
|
|
||||||
echo "${BODY}"
|
|
||||||
if echo "${BODY}" | python3 -c 'import json,os,sys; d=json.load(sys.stdin); sys.exit(0 if d.get("sha")==os.environ["EXPECTED_SHA"] else 1)'; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
sleep 10
|
|
||||||
done
|
|
||||||
echo "health SHA did not match ${EXPECTED_SHA}" >&2
|
|
||||||
exit 1
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
"justification": "The meals API ALB is the CloudFront HTTP origin for orders.seahaven.com. TLS and WAF terminate at CloudFront. Restricting the security group to the CloudFront managed prefix list would block GitHub-hosted weekly-menu HMAC publish, which must call the origin with X-Meals-Publish-Key. Application gates are HMAC on /api/publish, Cognito or Google Bearer on admin, and public submit only. Accepted as the HTTP-origin design for PLAT-215; TLS on the ALB is a follow-up."
|
"justification": "The meals API ALB is the CloudFront HTTP origin for orders.seahaven.com. TLS and WAF terminate at CloudFront. Restricting the security group to the CloudFront managed prefix list would block GitHub-hosted weekly-menu HMAC publish, which must call the origin with X-Meals-Publish-Key. Application gates are HMAC on /api/publish, Cognito or Google Bearer on admin, and public submit only. Accepted as the HTTP-origin design for PLAT-215; TLS on the ALB is a follow-up."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "checkov-CKV_AWS_111-40",
|
"id": "checkov-CKV_AWS_111-49",
|
||||||
"justification": "githubdeploy-meal-order-manager needs ecr:GetAuthorizationToken and ecs:RegisterTaskDefinition, both of which AWS documents as Resource *. Trust is pinned to environment:dev or environment:prod plus job_workflow_ref on deploy-api.yaml at refs/heads/main or refs/tags/v*. iam:PassRole is limited to the ECS task and execution roles. ECR push and SSM parameter reads are already resource-scoped."
|
"justification": "LINE SHIFT ONLY: the OIDC dual-claim change adds a workflow_ref condition and retargets job_workflow_ref, shifting github_deploy from 40 to 49. The permission document is unchanged. Original justification: githubdeploy-meal-order-manager needs ecr:GetAuthorizationToken and ecs:RegisterTaskDefinition, both of which AWS documents as Resource *. Trust is pinned to environment:dev or environment:prod, job_workflow_ref on org cd-hcp-fargate.yaml@*, and workflow_ref on the thin deploy-api.yaml caller at refs/heads/main or refs/tags/v*. iam:PassRole is limited to the ECS task and execution roles. ECR push and SSM parameter reads are already resource-scoped."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,8 +188,7 @@ meal-order-manager/
|
||||||
├── .github/workflows/
|
├── .github/workflows/
|
||||||
│ ├── weekly-menu.yml # Monday cron: scrape + HMAC publish + notify
|
│ ├── weekly-menu.yml # Monday cron: scrape + HMAC publish + notify
|
||||||
│ ├── deploy-api.yaml # Image CD to Fargate
|
│ ├── deploy-api.yaml # Image CD to Fargate
|
||||||
│ ├── ci.yml # PR checks (pytest, template JS, OpenAPI lint)
|
│ └── ci.yml # PR checks (lint, pytest, template JS, terraform, ci-complete)
|
||||||
│ └── ci-terraform.yaml # terraform fmt / validate
|
|
||||||
├── terraform/ # HCP Terraform (cluster, ALB, ECR, jobs queue)
|
├── terraform/ # HCP Terraform (cluster, ALB, ECR, jobs queue)
|
||||||
├── openapi.yaml # Employee HTTP contract (Redocly recommended)
|
├── openapi.yaml # Employee HTTP contract (Redocly recommended)
|
||||||
├── .redocly.yaml
|
├── .redocly.yaml
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# GitHub Actions OIDC role for .github/workflows/deploy-api.yaml.
|
# GitHub Actions OIDC role for the thin deploy-api.yaml caller of
|
||||||
|
# org reusable cd-hcp-fargate.yaml.
|
||||||
|
|
||||||
data "aws_iam_policy_document" "github_deploy_assume" {
|
data "aws_iam_policy_document" "github_deploy_assume" {
|
||||||
statement {
|
statement {
|
||||||
|
|
@ -29,6 +30,14 @@ data "aws_iam_policy_document" "github_deploy_assume" {
|
||||||
condition {
|
condition {
|
||||||
test = "StringLike"
|
test = "StringLike"
|
||||||
variable = "token.actions.githubusercontent.com:job_workflow_ref"
|
variable = "token.actions.githubusercontent.com:job_workflow_ref"
|
||||||
|
values = [
|
||||||
|
"Sea-Haven-Industries/.github/.github/workflows/cd-hcp-fargate.yaml@*",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
condition {
|
||||||
|
test = "StringLike"
|
||||||
|
variable = "token.actions.githubusercontent.com:workflow_ref"
|
||||||
values = [
|
values = [
|
||||||
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/heads/main",
|
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/heads/main",
|
||||||
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/tags/v*",
|
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/tags/v*",
|
||||||
|
|
|
||||||
35
tests/test_terraform_github_deploy.py
Normal file
35
tests/test_terraform_github_deploy.py
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
"""githubdeploy OIDC trust pins the org reusable and the thin caller."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
IAM = Path(__file__).resolve().parents[1] / "terraform" / "iam_github_deploy.tf"
|
||||||
|
|
||||||
|
|
||||||
|
def test_github_deploy_trust_uses_org_reusable_and_caller():
|
||||||
|
text = IAM.read_text()
|
||||||
|
assert "token.actions.githubusercontent.com:sub" in text
|
||||||
|
assert "repo:Sea-Haven-Industries/meal-order-manager:environment:dev" in text
|
||||||
|
assert "repo:Sea-Haven-Industries/meal-order-manager:environment:prod" in text
|
||||||
|
assert (
|
||||||
|
"Sea-Haven-Industries/.github/.github/workflows/cd-hcp-fargate.yaml@*" in text
|
||||||
|
)
|
||||||
|
assert "token.actions.githubusercontent.com:workflow_ref" in text
|
||||||
|
assert (
|
||||||
|
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/heads/main"
|
||||||
|
in text
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/tags/v*"
|
||||||
|
in text
|
||||||
|
)
|
||||||
|
assert "cd-hcp-spa.yaml" not in text
|
||||||
|
assert "token.actions.githubusercontent.com:workflow_ref" in text
|
||||||
|
assert (
|
||||||
|
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/heads/main"
|
||||||
|
in text
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
"Sea-Haven-Industries/meal-order-manager/.github/workflows/deploy-api.yaml@refs/tags/v*"
|
||||||
|
in text
|
||||||
|
)
|
||||||
|
assert "cd-hcp-spa.yaml" not in text
|
||||||
|
|
@ -36,4 +36,5 @@ def test_terraform_does_not_embed_a_sentry_dsn():
|
||||||
|
|
||||||
def test_deploy_api_injects_sentry_dsn_param():
|
def test_deploy_api_injects_sentry_dsn_param():
|
||||||
workflow = (ROOT / ".github/workflows/deploy-api.yaml").read_text()
|
workflow = (ROOT / ".github/workflows/deploy-api.yaml").read_text()
|
||||||
assert 'env["SENTRY_DSN_PARAM"] = "/meal-order-manager/sentry-dsn"' in workflow
|
assert "extra-task-env:" in workflow
|
||||||
|
assert '"SENTRY_DSN_PARAM":"/meal-order-manager/sentry-dsn"' in workflow
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue