From 564cdab83c413d0743c57cdf4ca2b273fc4c6f70 Mon Sep 17 00:00:00 2001 From: Ruslan Dashkin Date: Wed, 10 Dec 2025 12:40:20 -0600 Subject: [PATCH 1/6] Use OpenAPI spec for wake API --- infra/api/openapi-wake.yaml | 26 ++++++++++++++++++++++++++ infra/wake.tf | 26 +++++--------------------- 2 files changed, 31 insertions(+), 21 deletions(-) create mode 100644 infra/api/openapi-wake.yaml diff --git a/infra/api/openapi-wake.yaml b/infra/api/openapi-wake.yaml new file mode 100644 index 0000000..74e3ff2 --- /dev/null +++ b/infra/api/openapi-wake.yaml @@ -0,0 +1,26 @@ +openapi: 3.0.1 + +info: + title: docker-ecs-deployment — Wake API + version: "1.0.0" + +paths: + /: + get: + summary: Wake ECS service and redirect to app + operationId: getWake + responses: + "302": + description: Redirect to app or waiting page + "200": + description: HTML waiting/timeout page + x-amazon-apigateway-integration: + $ref: "#/components/x-amazon-apigateway-integrations/wake" + +components: + x-amazon-apigateway-integrations: + wake: + type: aws_proxy + uri: ${wake_lambda_invoke_arn} + httpMethod: POST + payloadFormatVersion: "2.0" \ No newline at end of file diff --git a/infra/wake.tf b/infra/wake.tf index c499564..2515178 100644 --- a/infra/wake.tf +++ b/infra/wake.tf @@ -93,33 +93,17 @@ resource "aws_lambda_function" "wake" { } ############################################ -# API Gateway (HTTP API) — Wake endpoint API +# API Gateway (HTTP API) — Wake endpoint API (OpenAPI-driven) +# Purpose: Define routes and Lambda integration via OpenAPI spec ############################################ resource "aws_apigatewayv2_api" "wake" { count = var.enable_wake_api ? 1 : 0 name = "${var.project_name}-wake" protocol_type = "HTTP" -} - -############################################ -# API Integration — Lambda proxy (payload v2.0) -############################################ -resource "aws_apigatewayv2_integration" "wake" { - count = var.enable_wake_api ? 1 : 0 - api_id = aws_apigatewayv2_api.wake[0].id - integration_type = "AWS_PROXY" - integration_uri = aws_lambda_function.wake[0].invoke_arn - payload_format_version = "2.0" -} -############################################ -# API Route — GET / -############################################ -resource "aws_apigatewayv2_route" "wake" { - count = var.enable_wake_api ? 1 : 0 - api_id = aws_apigatewayv2_api.wake[0].id - route_key = "GET /" - target = "integrations/${aws_apigatewayv2_integration.wake[0].id}" + body = templatefile("${path.module}/api/openapi-wake.yaml", { + wake_lambda_invoke_arn = "arn:aws:apigateway:${data.aws_region.current.id}:lambda:path/2015-03-31/functions/${aws_lambda_function.wake[0].arn}/invocations" + }) } ############################################ From 103ecb305285bb191bf59016103db90e02f728d0 Mon Sep 17 00:00:00 2001 From: Ruslan Dashkin Date: Wed, 10 Dec 2025 12:55:45 -0600 Subject: [PATCH 2/6] Document public wake API and tune Checkov for OpenAPI --- infra/api/openapi-wake.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/infra/api/openapi-wake.yaml b/infra/api/openapi-wake.yaml index 74e3ff2..f0570d9 100644 --- a/infra/api/openapi-wake.yaml +++ b/infra/api/openapi-wake.yaml @@ -3,7 +3,9 @@ openapi: 3.0.1 info: title: docker-ecs-deployment — Wake API version: "1.0.0" - + description: > + Public GET endpoint used only to trigger the wake Lambda for the demo ECS service. + No sensitive data is returned, security is enforced at the AWS/IAM boundary. paths: /: get: @@ -23,4 +25,4 @@ components: type: aws_proxy uri: ${wake_lambda_invoke_arn} httpMethod: POST - payloadFormatVersion: "2.0" \ No newline at end of file + payloadFormatVersion: "2.0" From ca669168e6c0419502b619a887bd0dab4f61971a Mon Sep 17 00:00:00 2001 From: Ruslan Dashkin Date: Wed, 10 Dec 2025 13:03:09 -0600 Subject: [PATCH 3/6] Simplify OpenAPI file and skip OPENAPI_4/5 checks --- infra/.checkov.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 infra/.checkov.yml diff --git a/infra/.checkov.yml b/infra/.checkov.yml new file mode 100644 index 0000000..f289dd8 --- /dev/null +++ b/infra/.checkov.yml @@ -0,0 +1,3 @@ +skip-check: + - CKV_OPENAPI_4 + - CKV_OPENAPI_5 From 94e1648b0f0dcf930bf79792d35a2eaab1d8f9dc Mon Sep 17 00:00:00 2001 From: Ruslan Dashkin Date: Wed, 10 Dec 2025 13:08:52 -0600 Subject: [PATCH 4/6] Skip OPENAPI_4/5 in root Checkov config --- .checkov.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.checkov.yml b/.checkov.yml index 92b2252..6757075 100644 --- a/.checkov.yml +++ b/.checkov.yml @@ -20,3 +20,6 @@ skip-check: - CKV_AWS_382 # 0.0.0.0/0 egress accepted for AWS APIs - CKV_AWS_260 # HTTP:80 from internet required for demo - CKV_TF_1 # No external modules pinned by git hash + # OpenAPI — wake endpoint осознанно публичный + - CKV_OPENAPI_4 # No global security scheme for public wake demo API + - CKV_OPENAPI_5 # Operation is intentionally unauthenticated From 0487b391a2e1f5fb96208e770e67a7663b91cb5d Mon Sep 17 00:00:00 2001 From: Ruslan Dashkin Date: Wed, 10 Dec 2025 13:21:47 -0600 Subject: [PATCH 5/6] Fix CI workflows comments and permissions --- .github/workflows/ci.yml | 46 +++++++++++++++++++----------- .github/workflows/terraform-ci.yml | 29 ++++++++++++------- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad304e3..44d61db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,8 @@ env: permissions: id-token: write contents: read + pull-requests: write + issues: write concurrency: group: ci-${{ github.ref }} @@ -100,22 +102,34 @@ jobs: - name: Comment on PR with build result if: ${{ github.event_name == 'pull_request' && success() }} uses: actions/github-script@v7 + continue-on-error: true with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const body = ` - ## Docker build result - - - Repository: \`${process.env.ECR_REPOSITORY}\` - - Region: \`${process.env.AWS_REGION}\` - - Image tag (PR SHA): \`${process.env.IMAGE_TAG}\` - - Workflow run: \`${process.env.GITHUB_RUN_NUMBER}\` - - Build for this pull request finished successfully (image built, not pushed). - `; - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body - }); + try { + const pr = context.payload.pull_request; + if (!pr) { + core.info('No pull_request context, skipping comment.'); + return; + } + + const body = ` + ## Docker build result + + - Repository: \`${process.env.ECR_REPOSITORY}\` + - Region: \`${process.env.AWS_REGION}\` + - Image tag (PR SHA): \`${process.env.IMAGE_TAG}\` + - Workflow run: \`${process.env.GITHUB_RUN_NUMBER}\` + + Build for this pull request finished successfully (image built, not pushed). + `; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body + }); + } catch (error) { + core.warning(`Failed to create Docker CI PR comment: ${error.message}`); + } diff --git a/.github/workflows/terraform-ci.yml b/.github/workflows/terraform-ci.yml index 30295b5..498ab64 100644 --- a/.github/workflows/terraform-ci.yml +++ b/.github/workflows/terraform-ci.yml @@ -71,24 +71,31 @@ jobs: - name: Comment on PR with Terraform CI result if: always() uses: actions/github-script@v7 + continue-on-error: true with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const conclusion = '${{ job.status }}'; - const symbols = { success: '✅', failure: '❌', cancelled: '⚪️' }; - const symbol = symbols[conclusion] || 'ℹ️'; - const body = - `${symbol} Terraform CI finished with status: **${conclusion}**\n\n` + - `Terraform versions tested: 1.6.6, 1.8.5, 1.9.5.\n` + - `See detailed results in the "Checks" tab.`; - const pr = context.payload.pull_request; - if (!pr) { - core.info('No pull_request context, skipping comment.'); - } else { + try { + const conclusion = '${{ job.status }}'; + const symbols = { success: '✅', failure: '❌', cancelled: '⚪️' }; + const symbol = symbols[conclusion] || 'ℹ️'; + const body = + `${symbol} Terraform CI finished with status: **${conclusion}**\n\n` + + `Terraform versions tested: 1.6.6, 1.8.5, 1.9.5.\n` + + `See detailed results in the "Checks" tab.`; + + const pr = context.payload.pull_request; + if (!pr) { + core.info('No pull_request context, skipping comment.'); + return; + } + await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: pr.number, body }); + } catch (error) { + core.warning(`Failed to create Terraform CI PR comment: ${error.message}`); } From 59fe59937af48cb93474183b56b73a336815c4e5 Mon Sep 17 00:00:00 2001 From: Ruslan Dashkin Date: Wed, 10 Dec 2025 13:23:10 -0600 Subject: [PATCH 6/6] Remove duplicated infra Checkov config --- infra/.checkov.yml | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 infra/.checkov.yml diff --git a/infra/.checkov.yml b/infra/.checkov.yml deleted file mode 100644 index f289dd8..0000000 --- a/infra/.checkov.yml +++ /dev/null @@ -1,3 +0,0 @@ -skip-check: - - CKV_OPENAPI_4 - - CKV_OPENAPI_5