diff --git a/.github/actions/deployment/preview/deploy-ecs-express-service/action.yml b/.github/actions/deployment/preview/deploy-ecs-express-service/action.yml index d784eca..dc6533d 100644 --- a/.github/actions/deployment/preview/deploy-ecs-express-service/action.yml +++ b/.github/actions/deployment/preview/deploy-ecs-express-service/action.yml @@ -33,6 +33,14 @@ inputs: description: 'Custom environment variables as JSON object, e.g. {"NAME":"VALUE"}' required: false default: '{}' + subnet-ids: + description: 'JSON array of subnet IDs for the service, e.g. ["subnet-abc"]. Must be provided together with security-group-ids.' + required: false + default: '' + security-group-ids: + description: 'JSON array of security group IDs for the service, e.g. ["sg-abc"]. Must be provided together with subnet-ids.' + required: false + default: '' outputs: service-url: @@ -145,6 +153,8 @@ runs: ENV_VARS_CONFIG: ${{ steps.prepare-env-vars.outputs.env_vars_config }} PLAINTEXT_ENV_VARS: ${{ steps.prepare-env-vars.outputs.plaintext_env_vars }} HEALTH_CHECK_ENDPOINT: ${{ inputs.health-endpoint }} + SUBNET_IDS: ${{ inputs.subnet-ids }} + SECURITY_GROUP_IDS: ${{ inputs.security-group-ids }} run: | secrets="$(jq -c '[to_entries[] | {name: .key, valueFrom: .value}]' <<< "$ENV_VARS_CONFIG")" plaintext="$(jq -c '[to_entries[] | {name: .key, value: .value}]' <<< "$PLAINTEXT_ENV_VARS")" @@ -170,6 +180,22 @@ runs: infrastructureRoleArn="${{ steps.set-service-variables.outputs.infrastructure_role_arn }}" taskRoleArn="${{ steps.set-service-variables.outputs.task_tole_arn }}" echo "Deploying Preview: ${{ steps.set-service-variables.outputs.service_name }} ($executionRoleArn, $infrastructureRoleArn, $taskRoleArn)..." + + NETWORK_ARGS=() + if [ -n "$SECURITY_GROUP_IDS" ] && [ -z "$SUBNET_IDS" ]; then + echo "Error: subnet-ids must be set when security-group-ids are provided." + exit 1 + fi + if [ -n "$SUBNET_IDS" ]; then + jq -e 'type == "array" and length > 0 and all(.[]; type == "string")' >/dev/null 2>&1 <<<"$SUBNET_IDS" || { echo 'Error: subnet-ids must be a non-empty JSON array of strings, e.g. ["subnet-abc"]'; exit 1; } + if [ -z "$SECURITY_GROUP_IDS" ]; then + echo "Error: security-group-ids must be set when subnet-ids are provided." + exit 1 + fi + jq -e 'type == "array" and length > 0 and all(.[]; type == "string")' >/dev/null 2>&1 <<<"$SECURITY_GROUP_IDS" || { echo 'Error: security-group-ids must be a non-empty JSON array of strings, e.g. ["sg-abc"]'; exit 1; } + NETWORK_CONFIG=$(jq -cn --argjson subnets "$SUBNET_IDS" --argjson sgs "$SECURITY_GROUP_IDS" '{subnets: $subnets, securityGroups: $sgs}') + NETWORK_ARGS=(--network-configuration "$NETWORK_CONFIG") + fi aws ecs create-express-gateway-service \ --service-name "${{ steps.set-service-variables.outputs.service_name }}" \ @@ -179,6 +205,7 @@ runs: --primary-container "$primary_container" \ --health-check-path "$HEALTH_CHECK_ENDPOINT" \ --scaling-target '{"minTaskCount": 1, "maxTaskCount": 1}' \ + "${NETWORK_ARGS[@]}" \ --region "${{ inputs.aws-region }}" serviceArn="arn:aws:ecs:${{ inputs.aws-region }}:${{ inputs.aws-account-id }}:service/default/${{ steps.set-service-variables.outputs.service_name }}" @@ -193,6 +220,8 @@ runs: ENV_VARS_CONFIG: ${{ steps.prepare-env-vars.outputs.env_vars_config }} PLAINTEXT_ENV_VARS: ${{ steps.prepare-env-vars.outputs.plaintext_env_vars }} HEALTH_CHECK_ENDPOINT: ${{ inputs.health-endpoint }} + SUBNET_IDS: ${{ inputs.subnet-ids }} + SECURITY_GROUP_IDS: ${{ inputs.security-group-ids }} run: | secrets="$(jq -c '[to_entries[] | {name: .key, valueFrom: .value}]' <<< "$ENV_VARS_CONFIG")" plaintext="$(jq -c '[to_entries[] | {name: .key, value: .value}]' <<< "$PLAINTEXT_ENV_VARS")" @@ -214,6 +243,22 @@ runs: SERVICE_ARN="${{ steps.check-service.outputs.service_arn }}" echo "Updating Preview: ${{ steps.set-service-variables.outputs.service_name }} ($SERVICE_ARN)..." + NETWORK_ARGS=() + if [ -n "$SECURITY_GROUP_IDS" ] && [ -z "$SUBNET_IDS" ]; then + echo "Error: subnet-ids must be set when security-group-ids are provided." + exit 1 + fi + if [ -n "$SUBNET_IDS" ]; then + jq -e 'type == "array" and length > 0 and all(.[]; type == "string")' >/dev/null 2>&1 <<<"$SUBNET_IDS" || { echo 'Error: subnet-ids must be a non-empty JSON array of strings, e.g. ["subnet-abc"]'; exit 1; } + if [ -z "$SECURITY_GROUP_IDS" ]; then + echo "Error: security-group-ids must be set when subnet-ids are provided." + exit 1 + fi + jq -e 'type == "array" and length > 0 and all(.[]; type == "string")' >/dev/null 2>&1 <<<"$SECURITY_GROUP_IDS" || { echo 'Error: security-group-ids must be a non-empty JSON array of strings, e.g. ["sg-abc"]'; exit 1; } + NETWORK_CONFIG=$(jq -cn --argjson subnets "$SUBNET_IDS" --argjson sgs "$SECURITY_GROUP_IDS" '{subnets: $subnets, securityGroups: $sgs}') + NETWORK_ARGS=(--network-configuration "$NETWORK_CONFIG") + fi + aws ecs update-express-gateway-service \ --service-arn "$SERVICE_ARN" \ --execution-role-arn "$executionRoleArn" \ @@ -221,6 +266,7 @@ runs: --primary-container "$primary_container" \ --health-check-path "$HEALTH_CHECK_ENDPOINT" \ --scaling-target '{"minTaskCount": 1, "maxTaskCount": 1}' \ + "${NETWORK_ARGS[@]}" \ --region "${{ inputs.aws-region }}" echo "Update started! $SERVICE_ARN" diff --git a/.github/workflows/deployment.preview.on-comment.yml b/.github/workflows/deployment.preview.on-comment.yml index 215ed20..baa8930 100644 --- a/.github/workflows/deployment.preview.on-comment.yml +++ b/.github/workflows/deployment.preview.on-comment.yml @@ -36,6 +36,16 @@ on: type: string default: '/' required: false + subnet-ids: + description: 'JSON array of subnet IDs for the ECS Express service, e.g. ["subnet-abc"]. Must be provided together with security-group-ids.' + required: false + type: string + default: '' + security-group-ids: + description: 'JSON array of security group IDs for the ECS Express service, e.g. ["sg-abc"]. Must be provided together with subnet-ids.' + required: false + type: string + default: '' jobs: trigger: @@ -66,7 +76,7 @@ jobs: preview: needs: trigger - uses: nsbno/platform-actions/.github/workflows/deployment.preview.yml@v2 + uses: nsbno/platform-actions/.github/workflows/deployment.preview.yml@vpc-option-preview-deployment with: health-endpoint: ${{ inputs.health-endpoint }} use-ecs-express-mode: ${{ inputs.use-ecs-express-mode }} @@ -78,6 +88,8 @@ jobs: skip-static-files-deployment: ${{ inputs.skip-static-files-deployment }} s3-static-files-path: ${{ inputs.s3-static-files-path }} custom-env-variables: ${{ inputs.custom-env-variables }} + subnet-ids: ${{ inputs.subnet-ids }} + security-group-ids: ${{ inputs.security-group-ids }} comment-handler: needs: [ trigger, preview ] diff --git a/.github/workflows/deployment.preview.yml b/.github/workflows/deployment.preview.yml index 459374f..011d18d 100644 --- a/.github/workflows/deployment.preview.yml +++ b/.github/workflows/deployment.preview.yml @@ -60,6 +60,16 @@ on: type: string default: '/' required: false + subnet-ids: + description: 'JSON array of subnet IDs for the ECS Express service, e.g. ["subnet-abc"]. Must be provided together with security-group-ids.' + required: false + type: string + default: '' + security-group-ids: + description: 'JSON array of security group IDs for the ECS Express service, e.g. ["sg-abc"]. Must be provided together with subnet-ids.' + required: false + type: string + default: '' permissions: contents: read @@ -165,7 +175,7 @@ jobs: - name: Deploy Preview (ECS) if: ${{ inputs.use-ecs-express-mode == true && (inputs.only-on-preview-comment == false || steps.check-comments.outputs.continue == 'true') }} id: deploy-ecs - uses: nsbno/platform-actions/.github/actions/deployment/preview/deploy-ecs-express-service@v2 + uses: nsbno/platform-actions/.github/actions/deployment/preview/deploy-ecs-express-service@vpc-option-preview-deployment with: health-endpoint: ${{ inputs.health-endpoint }} service-name: ${{ steps.deployment-info.outputs.ecs-service-name }} @@ -176,6 +186,8 @@ jobs: aws-region: ${{ vars.AWS_REGION }} git-event-number: ${{ inputs.git-event-number }} custom-env-variables: ${{ inputs.custom-env-variables }} + subnet-ids: ${{ inputs.subnet-ids }} + security-group-ids: ${{ inputs.security-group-ids }} - name: Push Mapping to DynamoDB and Comment domain name if: ${{ inputs.only-on-preview-comment == false || steps.check-comments.outputs.continue == 'true' }}