From f763772e5476d0acb8ce0260a34d059d642960a9 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 12:22:20 +0100 Subject: [PATCH 01/15] Testing --- .github/workflows/dev-build-upload.yml | 26 +++++++ .github/workflows/docker-build-upload.yml | 84 +++++++++++++---------- Dockerfile | 13 ++++ entrypoint.sh | 11 +++ 4 files changed, 98 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/dev-build-upload.yml create mode 100644 Dockerfile create mode 100644 entrypoint.sh diff --git a/.github/workflows/dev-build-upload.yml b/.github/workflows/dev-build-upload.yml new file mode 100644 index 0000000..83d5971 --- /dev/null +++ b/.github/workflows/dev-build-upload.yml @@ -0,0 +1,26 @@ +name: Demo Deployment Workflow + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build-push: + uses: .github/workflows/docker-build-upload.yml@${{ github.ref_name }} + with: + AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} + AWS_ROLE_TO_ASSUME: ${{ vars.AWS_ROLE_TO_ASSUME }} + ECR_REPOSITORY: 'gs-sandbox-github-actions' + NAME_PREFIX: 'gs-sandbox' + + DEPLOY_SCHEDULED_TASK: false # Only when you want to deploy scheduled tasks for the app + EXECUTION_NAME: 'github-actions-schedule' # It can be a list, only when you want to deploy scheduled tasks + + DEPLOY_ECS_SERVICE: false # Only when you want to deploy a ecs service for the app + SERVICE_NAME: 'github-actions-service' # Only when you want to deploy a ecs service + ECS_CLUSTER_NAME: 'gs-sandbox-ecs-cluster' # Only when you want to deploy a ecs service + ECS_DEV_DEPLOY: false # Only when you want to deploy a dev ecs service for the app \ No newline at end of file diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index 231c6e5..1e88eb5 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -8,13 +8,13 @@ name: Docker Build & Push # ##### GITHUB REQUIRED VARS ##### # AWS_DEFAULT_REGION: Already available in all /gsoftcolombia projects. # AWS_ROLE_TO_ASSUME: ARN of the role that aws-actions can assume. -# REPO_NAME: ECR Repository Name -# APP_NAME_PREFIX: Prefix of the task definition in AWS. -# APP_NAME_SUFFIX: Suffix/Postfix of the task definition in AWS. +# ECR_REPOSITORY: ECR Repository Name +# NAME_PREFIX: Prefix of the task definition in AWS. +# EXECUTION_NAME: Suffix/Postfix of the task definition in AWS. # - If there are multiple task-definitions you can add them separated by ';' e.g. customers;products # - If the Action is executed from Main, it expects to update a task definition -# with the name {APP_NAME_PREFIX}-prod-{APP_NAME_SUFFIX} -#  otherwise, {APP_NAME_PREFIX}-dev-{APP_NAME_SUFFIX} +# with the name {NAME_PREFIX}-prod-{EXECUTION_NAME} +#  otherwise, {NAME_PREFIX}-dev-{EXECUTION_NAME} # ##### USAGE TEMPLATE ##### # on: @@ -31,10 +31,14 @@ name: Docker Build & Push # with: # AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} # AWS_ROLE_TO_ASSUME: ${{ vars.AWS_ROLE_TO_ASSUME }} -# REPO_NAME: ${{ vars.REPO_NAME }} -# APP_NAME_PREFIX: ${{ vars.APP_NAME_PREFIX }} # Required for both ECS Services and Scheduled Tasks -# APP_NAME_SUFFIX: ${{ vars.APP_NAME_SUFFIX }} # Only when you want to deploy scheduled tasks -# ECS_SERVICE_NAME: ${{ vars.ECS_SERVICE_NAME }} # Only when you want to deploy ECS Services +# ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }} +# NAME_PREFIX: ${{ vars.NAME_PREFIX }} # Required for both ECS Services and Scheduled Tasks +# +# DEPLOY_SCHEDULED_TASK: true # Only when you want to deploy scheduled tasks for the app +# EXECUTION_NAME: ${{ vars.EXECUTION_NAME }} # Only when you want to deploy scheduled tasks +# +# DEPLOY_ECS_SERVICE: true # Only when you want to deploy a ecs service for the app +# SERVICE_NAME: ${{ vars.SERVICE_NAME }} # Only when you want to deploy ECS Services # ECS_CLUSTER_NAME: ${{ vars.ECS_CLUSTER_NAME }} # Only when you want to deploy ECS Services # ECS_DEV_DEPLOY: true # Only when you want to deploy a dev ECS Service for the app @@ -49,24 +53,32 @@ on: AWS_ROLE_TO_ASSUME: required: true type: string - REPO_NAME: + ECR_REPOSITORY: required: true type: string - APP_NAME_PREFIX: - required: false + NAME_PREFIX: + required: true type: string - APP_NAME_SUFFIX: + + DEPLOY_SCHEDULED_TASK: + required: true + type: boolean + EXECUTION_NAME: required: false type: string - default: '' - ECS_SERVICE_NAME: + default: 'missing_execution_name' # Only when you want to deploy scheduled tasks, it can be a list separated by ';' + + DEPLOY_ECS_SERVICE: + required: true + type: boolean + SERVICE_NAME: required: false type: string - default: '' + default: 'missing_service_name' # Only when you want to deploy a ecs service for the app ECS_CLUSTER_NAME: - required: false # Required if there is ECS_SERVICE_NAME + required: false # Required if there is SERVICE_NAME type: string - default: '' + default: 'missing_cluster_name' # Only when you want to deploy a ecs service for the app ECS_DEV_DEPLOY: required: false type: boolean @@ -114,7 +126,7 @@ jobs: id: build env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - ECR_REPOSITORY: ${{ inputs.REPO_NAME }} + ECR_REPOSITORY: ${{ inputs.ECR_REPOSITORY }} run: | IMAGE_ENV=$([ "$GITHUB_REF" = "refs/heads/main" ] && echo "prod" || echo "dev") IMAGE_TAG="${IMAGE_ENV}-${{ steps.commit-sha.outputs.COMMIT_SHORT_SHA }}" @@ -122,37 +134,37 @@ jobs: docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "FULL_IMAGE_URI=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT - - name: Update ECS Schedule Tasks # It only runs when there are APPs specified (SUFFIX) - if: ${{ inputs.APP_NAME_SUFFIX != '' }} - id: update-schedules + - name: Deploy ECS Schedule Tasks + if: ${{ inputs.DEPLOY_SCHEDULED_TASK == true }} + id: deploy-schedules run: | echo "Updating Task Definitions" export IFS=";" - SUFFIXES="${{ inputs.APP_NAME_SUFFIX }}" + SUFFIXES="${{ inputs.EXECUTION_NAME }}" for app in $SUFFIXES; do if ! aws ecs describe-task-definition \ - --task-definition ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${app} \ + --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${app} \ --region=${{ inputs.AWS_DEFAULT_REGION }} &> /dev/null; then echo "WARNING: Task definition $TASK_DEFINITION does not exist." else echo "Updating Task-Definition for: ${app} ..." - TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${app} --region=${{ inputs.AWS_DEFAULT_REGION }}) + TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${app} --region=${{ inputs.AWS_DEFAULT_REGION }}) NEW_TASK_DEFINITION=$(echo $TASK_DEFINITION | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.taskDefinition | .containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') aws ecs register-task-definition --region ${{ inputs.AWS_DEFAULT_REGION }} --cli-input-json "$NEW_TASK_DEFINITION" fi done - - name: Render Amazon ECS Service Task Definition # It only runs when there is an ECS_SERVICE_NAME specified. - if: ${{ inputs.ECS_SERVICE_NAME != '' }} + - name: Render Amazon ECS Service Task Definition # It only runs when there is an SERVICE_NAME specified. + if: ${{ inputs.DEPLOY_ECS_SERVICE == true }} id: render-web-container uses: aws-actions/amazon-ecs-render-task-definition@v1 with: - task-definition-family: ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }} - container-name: ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }} + task-definition-family: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} + container-name: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} image: ${{ steps.build.outputs.FULL_IMAGE_URI }} - name: Generate appspec.yaml dynamically - if: ${{ inputs.ECS_SERVICE_NAME != '' }} + if: ${{ inputs.DEPLOY_ECS_SERVICE == true }} id: generate-appspec run: | cat < appspec.yaml @@ -161,19 +173,19 @@ jobs: - TargetService: Type: AWS::ECS::Service Properties: - TaskDefinition: "${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }}" + TaskDefinition: "${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }}" LoadBalancerInfo: - ContainerName: "${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }}" + ContainerName: "${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }}" ContainerPort: 80 EOF - name: Deploy to Amazon ECS service - if: ${{ inputs.ECS_SERVICE_NAME != '' && (steps.commit-sha.outputs.TASK_ENV == 'prod' || ( steps.commit-sha.outputs.TASK_ENV == 'dev' && inputs.ECS_DEV_DEPLOY == true )) }} + if: ${{ inputs.DEPLOY_ECS_SERVICE == true && (steps.commit-sha.outputs.TASK_ENV == 'prod' || ( steps.commit-sha.outputs.TASK_ENV == 'dev' && inputs.ECS_DEV_DEPLOY == true )) }} uses: aws-actions/amazon-ecs-deploy-task-definition@v2 with: task-definition: ${{ steps.render-web-container.outputs.task-definition }} - service: ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }} + service: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} cluster: ${{ inputs.ECS_CLUSTER_NAME }} wait-for-service-stability: true - codedeploy-application: ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }} - codedeploy-deployment-group: ${{ inputs.APP_NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.ECS_SERVICE_NAME }} \ No newline at end of file + codedeploy-application: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} + codedeploy-deployment-group: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..517c8c6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:24.04 + +ENV LC_ALL=en_US.UTF-8 +ENV LANG=en_US.UTF-8 + +RUN apt-get update && apt-get install -y +RUN apt-get install -y apache2 + +COPY ./entrypoint.sh /app/ +RUN chmod +x /app/entrypoint.sh + +ENTRYPOINT ["/app/entrypoint.sh"] +CMD ["apache2ctl", "-D" ,"FOREGROUND"] \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..f64c689 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e # Exit on error + +name_prefix="gs-sandbox" +environment="${environment}" +execution_name="demo" + +echo "This is ${name_prefix}-${environment}-${execution_name} and it is ready to start..." + +# Run the main application command +exec "$@" \ No newline at end of file From 89201d25f5aaec3310359e481f2ad7977766e937 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 12:26:14 +0100 Subject: [PATCH 02/15] fix --- .github/workflows/dev-build-upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dev-build-upload.yml b/.github/workflows/dev-build-upload.yml index 83d5971..3fa6824 100644 --- a/.github/workflows/dev-build-upload.yml +++ b/.github/workflows/dev-build-upload.yml @@ -10,7 +10,7 @@ on: jobs: build-push: - uses: .github/workflows/docker-build-upload.yml@${{ github.ref_name }} + uses: ./.github/workflows/docker-build-upload.yml with: AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} AWS_ROLE_TO_ASSUME: ${{ vars.AWS_ROLE_TO_ASSUME }} From bca27484c823a4b9250f00bb1a72bbc7dbd3d6d4 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:26:12 +0100 Subject: [PATCH 03/15] Adding scheduled_task json file --- .config/scheduled_task.json | 30 +++++++++++++++++++++++ .github/workflows/dev-build-upload.yml | 2 +- .github/workflows/docker-build-upload.yml | 16 ++++++------ 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 .config/scheduled_task.json diff --git a/.config/scheduled_task.json b/.config/scheduled_task.json new file mode 100644 index 0000000..19d4a33 --- /dev/null +++ b/.config/scheduled_task.json @@ -0,0 +1,30 @@ +{ + "containerDefinitions": [ + { + "name": "gs-sandbox-dev-github-actions-schedule", + "image": "public.ecr.aws/docker/library/busybox", + "cpu": 0, + "portMappings": [], + "essential": true, + "command": [ + "bash", + "-c", + "echo bootstrap task; exit 0" + ], + "environment": [], + "mountPoints": [], + "volumesFrom": [], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "gs-sandbox-dev-github-actions-schedule", + "awslogs-region": "us-east-2", + "awslogs-stream-prefix": "ecs" + } + }, + "systemControls": [] + } + ], + "cpu": "256", + "memory": "512" +} \ No newline at end of file diff --git a/.github/workflows/dev-build-upload.yml b/.github/workflows/dev-build-upload.yml index 3fa6824..49b81da 100644 --- a/.github/workflows/dev-build-upload.yml +++ b/.github/workflows/dev-build-upload.yml @@ -18,7 +18,7 @@ jobs: NAME_PREFIX: 'gs-sandbox' DEPLOY_SCHEDULED_TASK: false # Only when you want to deploy scheduled tasks for the app - EXECUTION_NAME: 'github-actions-schedule' # It can be a list, only when you want to deploy scheduled tasks + EXECUTION_NAME: 'github-actions-schedule' # It can be a list separated by ';', only when you want to deploy scheduled tasks DEPLOY_ECS_SERVICE: false # Only when you want to deploy a ecs service for the app SERVICE_NAME: 'github-actions-service' # Only when you want to deploy a ecs service diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index 1e88eb5..ea4b6ac 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -140,16 +140,18 @@ jobs: run: | echo "Updating Task Definitions" export IFS=";" - SUFFIXES="${{ inputs.EXECUTION_NAME }}" - for app in $SUFFIXES; do + list_execution_name="${{ inputs.EXECUTION_NAME }}" + for execution_name in $list_execution_name; do if ! aws ecs describe-task-definition \ - --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${app} \ + --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} \ --region=${{ inputs.AWS_DEFAULT_REGION }} &> /dev/null; then - echo "WARNING: Task definition $TASK_DEFINITION does not exist." + echo "ERROR: Task definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} does not exist." + exit 1 else - echo "Updating Task-Definition for: ${app} ..." - TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${app} --region=${{ inputs.AWS_DEFAULT_REGION }}) - NEW_TASK_DEFINITION=$(echo $TASK_DEFINITION | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.taskDefinition | .containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') + echo "Updating Task-Definition for: ${execution_name} ..." + TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} --region=${{ inputs.AWS_DEFAULT_REGION }}) + updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/scheduled_task.json '.taskDefinition | .containerDefinitions = $config[0].containerDefinitions | .cpu = $config[0].cpu | .memory = $config[0].memory') + NEW_TASK_DEFINITION=$(echo $updated_task_definition | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') aws ecs register-task-definition --region ${{ inputs.AWS_DEFAULT_REGION }} --cli-input-json "$NEW_TASK_DEFINITION" fi done From ee9b25a650654e6cef546b0101a098109d16b709 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:28:54 +0100 Subject: [PATCH 04/15] fix --- .config/{scheduled_task.json => github-actions-schedule.json} | 0 .github/workflows/dev-build-upload.yml | 2 +- .github/workflows/docker-build-upload.yml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename .config/{scheduled_task.json => github-actions-schedule.json} (100%) diff --git a/.config/scheduled_task.json b/.config/github-actions-schedule.json similarity index 100% rename from .config/scheduled_task.json rename to .config/github-actions-schedule.json diff --git a/.github/workflows/dev-build-upload.yml b/.github/workflows/dev-build-upload.yml index 49b81da..467a192 100644 --- a/.github/workflows/dev-build-upload.yml +++ b/.github/workflows/dev-build-upload.yml @@ -17,7 +17,7 @@ jobs: ECR_REPOSITORY: 'gs-sandbox-github-actions' NAME_PREFIX: 'gs-sandbox' - DEPLOY_SCHEDULED_TASK: false # Only when you want to deploy scheduled tasks for the app + DEPLOY_SCHEDULED_TASK: true # Only when you want to deploy scheduled tasks for the app EXECUTION_NAME: 'github-actions-schedule' # It can be a list separated by ';', only when you want to deploy scheduled tasks DEPLOY_ECS_SERVICE: false # Only when you want to deploy a ecs service for the app diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index ea4b6ac..836cf73 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -150,7 +150,7 @@ jobs: else echo "Updating Task-Definition for: ${execution_name} ..." TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} --region=${{ inputs.AWS_DEFAULT_REGION }}) - updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/scheduled_task.json '.taskDefinition | .containerDefinitions = $config[0].containerDefinitions | .cpu = $config[0].cpu | .memory = $config[0].memory') + updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/${execution_name}.json '.taskDefinition | .containerDefinitions = $config[0].containerDefinitions | .cpu = $config[0].cpu | .memory = $config[0].memory') NEW_TASK_DEFINITION=$(echo $updated_task_definition | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') aws ecs register-task-definition --region ${{ inputs.AWS_DEFAULT_REGION }} --cli-input-json "$NEW_TASK_DEFINITION" fi From 50f552985642ab79d428ef183d1590d4448494c8 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:34:42 +0100 Subject: [PATCH 05/15] making it more dynamic --- .config/github-actions-schedule.json | 4 ++-- .github/workflows/docker-build-upload.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index 19d4a33..50db87c 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -7,7 +7,7 @@ "portMappings": [], "essential": true, "command": [ - "bash", + "/bin/bash", "-c", "echo bootstrap task; exit 0" ], @@ -26,5 +26,5 @@ } ], "cpu": "256", - "memory": "512" + "memory": "513" } \ No newline at end of file diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index 836cf73..aff7437 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -150,7 +150,7 @@ jobs: else echo "Updating Task-Definition for: ${execution_name} ..." TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} --region=${{ inputs.AWS_DEFAULT_REGION }}) - updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/${execution_name}.json '.taskDefinition | .containerDefinitions = $config[0].containerDefinitions | .cpu = $config[0].cpu | .memory = $config[0].memory') + updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/${execution_name}.json '.taskDefinition |= . * $config[0]') NEW_TASK_DEFINITION=$(echo $updated_task_definition | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') aws ecs register-task-definition --region ${{ inputs.AWS_DEFAULT_REGION }} --cli-input-json "$NEW_TASK_DEFINITION" fi From 33c4466fc1e99cafec76443a14dec349a01107ea Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:37:55 +0100 Subject: [PATCH 06/15] test again --- .github/workflows/docker-build-upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index aff7437..79ddd5e 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -150,7 +150,7 @@ jobs: else echo "Updating Task-Definition for: ${execution_name} ..." TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} --region=${{ inputs.AWS_DEFAULT_REGION }}) - updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/${execution_name}.json '.taskDefinition |= . * $config[0]') + updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/${execution_name}.json '.taskDefinition as $base | $config[0] as $updates | reduce ($updates | keys[]) as $key ($base; .[$key] = $updates[$key])') NEW_TASK_DEFINITION=$(echo $updated_task_definition | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') aws ecs register-task-definition --region ${{ inputs.AWS_DEFAULT_REGION }} --cli-input-json "$NEW_TASK_DEFINITION" fi From 22bb635178136cafcde36d07dc59a30f8f0c2ded Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:39:14 +0100 Subject: [PATCH 07/15] test --- .config/github-actions-schedule.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index 50db87c..5cf9182 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -26,5 +26,5 @@ } ], "cpu": "256", - "memory": "513" + "memory": "512" } \ No newline at end of file From a39cc123a91a159fc0b0e7f8f5eab14f777bf2bc Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:40:51 +0100 Subject: [PATCH 08/15] test --- .config/github-actions-schedule.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index 5cf9182..c549ef0 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -9,7 +9,7 @@ "command": [ "/bin/bash", "-c", - "echo bootstrap task; exit 0" + "echo test performed; exit 0" ], "environment": [], "mountPoints": [], @@ -24,7 +24,5 @@ }, "systemControls": [] } - ], - "cpu": "256", - "memory": "512" + ] } \ No newline at end of file From 6a0d292fdd99fecfdebc892ef5afa8c8e80fe076 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:43:10 +0100 Subject: [PATCH 09/15] small change --- .config/github-actions-schedule.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index c549ef0..61b2743 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -2,14 +2,13 @@ "containerDefinitions": [ { "name": "gs-sandbox-dev-github-actions-schedule", - "image": "public.ecr.aws/docker/library/busybox", "cpu": 0, "portMappings": [], "essential": true, "command": [ "/bin/bash", "-c", - "echo test performed; exit 0" + "echo Scheduled Task Executed; exit 0" ], "environment": [], "mountPoints": [], @@ -24,5 +23,7 @@ }, "systemControls": [] } - ] + ], + "cpu": "256", + "memory": "512" } \ No newline at end of file From 6e4e91351ba365addcc85b5fc1cd72131d952b0b Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 14:52:22 +0100 Subject: [PATCH 10/15] Making image smaller --- .config/github-actions-schedule.json | 2 +- Dockerfile | 10 ++---- README.md | 47 ++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index 61b2743..f193a99 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -6,7 +6,7 @@ "portMappings": [], "essential": true, "command": [ - "/bin/bash", + "/bin/sh", "-c", "echo Scheduled Task Executed; exit 0" ], diff --git a/Dockerfile b/Dockerfile index 517c8c6..cfbdd3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,7 @@ -FROM ubuntu:24.04 - -ENV LC_ALL=en_US.UTF-8 -ENV LANG=en_US.UTF-8 - -RUN apt-get update && apt-get install -y -RUN apt-get install -y apache2 +FROM httpd:latest COPY ./entrypoint.sh /app/ RUN chmod +x /app/entrypoint.sh ENTRYPOINT ["/app/entrypoint.sh"] -CMD ["apache2ctl", "-D" ,"FOREGROUND"] \ No newline at end of file +CMD ["httpd-foreground"] \ No newline at end of file diff --git a/README.md b/README.md index ddc0a08..7a61aea 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,50 @@ This is the main repo where our github actions and also general technical documentation are located. +## Reusable Workflows + +### Docker Build & Push + +This reusable workflow builds a Dockerfile located in the root of the project, pushes the new Docker image to an ECR Registry, and optionally updates ECS task definitions for services or scheduled tasks. + +#### Usage + +To use this workflow, call it from another workflow file as shown in `.github/workflows/dev-build-upload.yml`: + +```yaml +jobs: + build-push: + uses: gsoftcolombia/github-actions/.github/workflows/docker-build-upload.yml@main + with: + AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} + AWS_ROLE_TO_ASSUME: ${{ vars.AWS_ROLE_TO_ASSUME }} + ECR_REPOSITORY: ${{ vars.ECR_REPOSITORY }} + NAME_PREFIX: ${{ vars.NAME_PREFIX }} + + DEPLOY_SCHEDULED_TASK: true + EXECUTION_NAME: ${{ vars.EXECUTION_NAME }} + + DEPLOY_ECS_SERVICE: false + SERVICE_NAME: ${{ vars.SERVICE_NAME }} + ECS_CLUSTER_NAME: ${{ vars.ECS_CLUSTER_NAME }} + ECS_DEV_DEPLOY: false +``` + +#### Required Variables + +- `AWS_DEFAULT_REGION`: AWS region (available in all /gsoftcolombia projects). +- `AWS_ROLE_TO_ASSUME`: ARN of the role for aws-actions to assume. +- `ECR_REPOSITORY`: ECR Repository Name. +- `NAME_PREFIX`: Prefix of the task definition in AWS. + +#### Optional Inputs + +- `DEPLOY_SCHEDULED_TASK`: Set to true to deploy scheduled tasks. +- `EXECUTION_NAME`: Suffix for scheduled task definitions (can be a list separated by ';'). +- `DEPLOY_ECS_SERVICE`: Set to true to deploy an ECS service. +- `SERVICE_NAME`: Name of the ECS service. +- `ECS_CLUSTER_NAME`: Name of the ECS cluster. +- `ECS_DEV_DEPLOY`: Set to true to deploy to dev environment. + +For more details, see the workflow file at `.github/workflows/docker-build-upload.yml`. + From 2983c712bd1cdc391982926a98b20bc929a489b8 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 16:59:14 +0100 Subject: [PATCH 11/15] test service --- .github/workflows/dev-build-upload.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dev-build-upload.yml b/.github/workflows/dev-build-upload.yml index 467a192..2f0176f 100644 --- a/.github/workflows/dev-build-upload.yml +++ b/.github/workflows/dev-build-upload.yml @@ -1,9 +1,6 @@ name: Demo Deployment Workflow on: - push: - branches: - - main pull_request: branches: - main @@ -20,7 +17,7 @@ jobs: DEPLOY_SCHEDULED_TASK: true # Only when you want to deploy scheduled tasks for the app EXECUTION_NAME: 'github-actions-schedule' # It can be a list separated by ';', only when you want to deploy scheduled tasks - DEPLOY_ECS_SERVICE: false # Only when you want to deploy a ecs service for the app - SERVICE_NAME: 'github-actions-service' # Only when you want to deploy a ecs service + DEPLOY_ECS_SERVICE: true # Only when you want to deploy a ecs service for the app + SERVICE_NAME: 'demo-svc' # Only when you want to deploy a ecs service ECS_CLUSTER_NAME: 'gs-sandbox-ecs-cluster' # Only when you want to deploy a ecs service - ECS_DEV_DEPLOY: false # Only when you want to deploy a dev ecs service for the app \ No newline at end of file + ECS_DEV_DEPLOY: true # Only when you want to deploy a dev ecs service for the app \ No newline at end of file From dd39af8075748a9c8c39a8c05046afc2c8250f3c Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 17:07:03 +0100 Subject: [PATCH 12/15] fix --- .github/workflows/docker-build-upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index 79ddd5e..f2e01e1 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -122,7 +122,6 @@ jobs: echo "TASK_ENV=$TASK_ENV" >> $GITHUB_OUTPUT - name: Build and Push to ECR - continue-on-error: true # for cases when the image is already pushed id: build env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} @@ -131,6 +130,7 @@ jobs: IMAGE_ENV=$([ "$GITHUB_REF" = "refs/heads/main" ] && echo "prod" || echo "dev") IMAGE_TAG="${IMAGE_ENV}-${{ steps.commit-sha.outputs.COMMIT_SHORT_SHA }}" docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . + aws ecr batch-delete-image --repository-name $ECR_REPOSITORY --image-ids imageTag=$IMAGE_TAG 2>/dev/null || true docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG echo "FULL_IMAGE_URI=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT From a0a6de9b65d0a60dd86788b238d0910fe53cca97 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 7 Mar 2026 18:27:50 +0100 Subject: [PATCH 13/15] fix --- .github/workflows/docker-build-upload.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index f2e01e1..204611e 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -188,6 +188,6 @@ jobs: task-definition: ${{ steps.render-web-container.outputs.task-definition }} service: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} cluster: ${{ inputs.ECS_CLUSTER_NAME }} - wait-for-service-stability: true + wait-for-service-stability: false codedeploy-application: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} codedeploy-deployment-group: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} \ No newline at end of file From 5d97f5859a363fd85aa24dd6ae45cce287a2bca3 Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 28 Mar 2026 20:56:14 +0100 Subject: [PATCH 14/15] Testing, launching service and scheduled task --- .config/github-actions-schedule.json | 33 ++++++----------------- .github/workflows/docker-build-upload.yml | 28 ++++++++++++++++--- README.md | 6 +++++ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index f193a99..23d2310 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -1,29 +1,12 @@ { - "containerDefinitions": [ + "containerDefinitions": [ + { + "secrets": [ { - "name": "gs-sandbox-dev-github-actions-schedule", - "cpu": 0, - "portMappings": [], - "essential": true, - "command": [ - "/bin/sh", - "-c", - "echo Scheduled Task Executed; exit 0" - ], - "environment": [], - "mountPoints": [], - "volumesFrom": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-group": "gs-sandbox-dev-github-actions-schedule", - "awslogs-region": "us-east-2", - "awslogs-stream-prefix": "ecs" - } - }, - "systemControls": [] + "name": "secrets", + "valueFrom": "/dev/app/demo-secret" } - ], - "cpu": "256", - "memory": "512" + ] + } + ] } \ No newline at end of file diff --git a/.github/workflows/docker-build-upload.yml b/.github/workflows/docker-build-upload.yml index 204611e..9258a52 100644 --- a/.github/workflows/docker-build-upload.yml +++ b/.github/workflows/docker-build-upload.yml @@ -142,6 +142,12 @@ jobs: export IFS=";" list_execution_name="${{ inputs.EXECUTION_NAME }}" for execution_name in $list_execution_name; do + config_file=".config/${execution_name}.json" + if [ ! -f "$config_file" ]; then + echo "ERROR: Missing scheduled task config file: $config_file" + exit 1 + fi + if ! aws ecs describe-task-definition \ --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} \ --region=${{ inputs.AWS_DEFAULT_REGION }} &> /dev/null; then @@ -150,8 +156,22 @@ jobs: else echo "Updating Task-Definition for: ${execution_name} ..." TASK_DEFINITION=$(aws ecs describe-task-definition --task-definition ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${execution_name} --region=${{ inputs.AWS_DEFAULT_REGION }}) - updated_task_definition=$(echo $TASK_DEFINITION | jq --slurpfile config .config/${execution_name}.json '.taskDefinition as $base | $config[0] as $updates | reduce ($updates | keys[]) as $key ($base; .[$key] = $updates[$key])') - NEW_TASK_DEFINITION=$(echo $updated_task_definition | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') + updated_task_definition=$(echo "$TASK_DEFINITION" | jq --slurpfile config ".config/${execution_name}.json" ' + .taskDefinition as $base + | ($config[0] // {}) as $updates + | ($updates.containerDefinitions // []) as $container_updates + | ($base * ($updates | del(.containerDefinitions))) as $merged + | if ($container_updates | length) > 0 then + $merged + | .containerDefinitions = [ + range(0; ($merged.containerDefinitions | length)) as $index + | (($merged.containerDefinitions[$index] // {}) * ($container_updates[$index] // {})) + ] + else + $merged + end + ') + NEW_TASK_DEFINITION=$(echo "$updated_task_definition" | jq --arg IMAGE "${{ steps.build.outputs.FULL_IMAGE_URI }}" '.containerDefinitions[0].image = $IMAGE | del(.taskDefinitionArn) | del(.revision) | del(.status) | del(.requiresAttributes) | del(.compatibilities) | del(.registeredAt) | del(.registeredBy)') aws ecs register-task-definition --region ${{ inputs.AWS_DEFAULT_REGION }} --cli-input-json "$NEW_TASK_DEFINITION" fi done @@ -160,10 +180,12 @@ jobs: if: ${{ inputs.DEPLOY_ECS_SERVICE == true }} id: render-web-container uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: + with: task-definition-family: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} container-name: ${{ inputs.NAME_PREFIX }}-${{ steps.commit-sha.outputs.TASK_ENV }}-${{ inputs.SERVICE_NAME }} image: ${{ steps.build.outputs.FULL_IMAGE_URI }} + environment-variables: | + ENVIRONMENT=${{ steps.commit-sha.outputs.TASK_ENV }} - name: Generate appspec.yaml dynamically if: ${{ inputs.DEPLOY_ECS_SERVICE == true }} diff --git a/README.md b/README.md index 7a61aea..aaa30a9 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ This is the main repo where our github actions and also general technical docume This reusable workflow builds a Dockerfile located in the root of the project, pushes the new Docker image to an ECR Registry, and optionally updates ECS task definitions for services or scheduled tasks. +For scheduled tasks, the caller repository can define runtime overrides under `.config/`: + +- Scheduled tasks must provide `.config/.json`. + +The file is merged with the current active task definition before the image tag is updated, so the application repository owns the scheduled-task runtime fields without Terraform managing them. + #### Usage To use this workflow, call it from another workflow file as shown in `.github/workflows/dev-build-upload.yml`: From ea98d7278baed1013bfa7dbcf6cf13149989d88b Mon Sep 17 00:00:00 2001 From: Tecnologia Gsoft Date: Sat, 28 Mar 2026 21:00:28 +0100 Subject: [PATCH 15/15] Test when there are no secrets in the schedule --- .config/github-actions-schedule.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.config/github-actions-schedule.json b/.config/github-actions-schedule.json index 23d2310..14b290d 100644 --- a/.config/github-actions-schedule.json +++ b/.config/github-actions-schedule.json @@ -1,12 +1,6 @@ { "containerDefinitions": [ { - "secrets": [ - { - "name": "secrets", - "valueFrom": "/dev/app/demo-secret" - } - ] } ] } \ No newline at end of file