diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index 6935afc..6a2fb96 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -13,7 +13,7 @@ permissions: actions: none checks: none issues: none - packages: none + packages: write # required to push images to ghcr.io pull-requests: write # required to comment on merged PRs statuses: none @@ -77,47 +77,47 @@ jobs: role-to-assume: ${{ secrets.AWS_ROLE_DEV }} aws-region: ${{ secrets.AWS_REGION }} - - name: Log in to ECR + - name: Log in to ghcr.io if: env.SKIP_DEPLOY != 'true' - id: ecr-login - uses: aws-actions/amazon-ecr-login@v2 + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image if: env.SKIP_DEPLOY != 'true' env: - REGISTRY: ${{ steps.ecr-login.outputs.registry }} + IMAGE: ghcr.io/innovationtreehouse/arbor-agent SHA: ${{ github.event.workflow_run.head_sha }} run: | docker buildx build --platform linux/arm64 \ --push \ - -t $REGISTRY/arbor-agent:$SHA \ - -t $REGISTRY/arbor-agent:dev \ + -t $IMAGE:$SHA \ + -t $IMAGE:dev \ -f packages/agent/Dockerfile . - name: Build and push migrate image if: env.SKIP_DEPLOY != 'true' env: - REGISTRY: ${{ steps.ecr-login.outputs.registry }} + IMAGE: ghcr.io/innovationtreehouse/arbor-agent SHA: ${{ github.event.workflow_run.head_sha }} run: | docker buildx build --platform linux/arm64 \ --target migrate \ --push \ - -t $REGISTRY/arbor-agent:migrate-$SHA \ - -t $REGISTRY/arbor-agent:migrate-dev \ + -t $IMAGE:migrate-$SHA \ + -t $IMAGE:migrate-dev \ -f packages/agent/Dockerfile . - name: Verify image is pullable (dev) if: env.SKIP_DEPLOY != 'true' env: + IMAGE: ghcr.io/innovationtreehouse/arbor-agent SHA: ${{ github.event.workflow_run.head_sha }} run: | - aws ecr describe-images \ - --repository-name arbor-agent \ - --image-ids imageTag=$SHA \ - --query 'imageDetails[0].imageTags' \ - --output text - echo "Image $SHA confirmed in ECR." + docker buildx imagetools inspect $IMAGE:$SHA >/dev/null + echo "Image $SHA confirmed in ghcr.io." - name: Build Lambda zip if: env.SKIP_DEPLOY != 'true' @@ -174,7 +174,7 @@ jobs: aws ecs describe-task-definition \ --task-definition arbor-migrate-dev \ --query taskDefinition \ - | jq --arg img "$ACCOUNT.dkr.ecr.$REGION.amazonaws.com/arbor-agent:migrate-$SHA" \ + | jq --arg img "ghcr.io/innovationtreehouse/arbor-agent:migrate-$SHA" \ 'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy) | .containerDefinitions[0].image = $img @@ -201,7 +201,7 @@ jobs: --cluster arbor-dev \ --task-definition "${{ steps.register-migrate-task-def-dev.outputs.task_def_arn }}" \ --launch-type FARGATE \ - --network-configuration "awsvpcConfiguration={subnets=[${{ secrets.SUBNET_IDS_DEV }}],securityGroups=[${{ secrets.SECURITY_GROUP_ID_DEV }}],assignPublicIp=DISABLED}" \ + --network-configuration "awsvpcConfiguration={subnets=[${{ secrets.SUBNET_IDS_DEV }}],securityGroups=[${{ secrets.SECURITY_GROUP_ID_DEV }}],assignPublicIp=ENABLED}" \ --overrides "{\"containerOverrides\":[{\"name\":\"arbor-migrate\",\"environment\":[{\"name\":\"DATABASE_URL\",\"value\":\"${{ secrets.DATABASE_URL_DEV }}\"}]}]}" \ --query 'tasks[0].taskArn' --output text) echo "Migration task: $TASK_ARN" @@ -254,7 +254,7 @@ jobs: aws ecs describe-task-definition \ --task-definition arbor-agent-dev \ --query taskDefinition \ - | jq --arg img "$ACCOUNT.dkr.ecr.$REGION.amazonaws.com/arbor-agent:$SHA" \ + | jq --arg img "ghcr.io/innovationtreehouse/arbor-agent:$SHA" \ 'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy) | .containerDefinitions[0].image = $img diff --git a/.github/workflows/promote-prod.yml b/.github/workflows/promote-prod.yml index 50f0233..3ac3851 100644 --- a/.github/workflows/promote-prod.yml +++ b/.github/workflows/promote-prod.yml @@ -13,7 +13,7 @@ permissions: actions: none checks: none issues: none - packages: none + packages: write # required to push images to ghcr.io pull-requests: write # required to comment on merged PRs statuses: none @@ -82,34 +82,33 @@ jobs: role-to-assume: ${{ secrets.AWS_ROLE_PROD }} aws-region: ${{ secrets.AWS_REGION }} - - name: Log in to ECR - id: ecr-login - uses: aws-actions/amazon-ecr-login@v2 + - name: Log in to ghcr.io + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Verify SHA was deployed to dev env: - REGISTRY: ${{ steps.ecr-login.outputs.registry }} + IMAGE: ghcr.io/innovationtreehouse/arbor-agent SHA_INPUT: ${{ inputs.sha }} run: | # Fail fast before migrations if this SHA was never built and pushed to dev - aws ecr describe-images \ - --repository-name arbor-agent \ - --image-ids imageTag=$SHA_INPUT \ - --query 'imageDetails[0].imageTags' \ - --output text - echo "SHA $SHA_INPUT confirmed in ECR." + docker buildx imagetools inspect $IMAGE:$SHA_INPUT >/dev/null + echo "SHA $SHA_INPUT confirmed in ghcr.io." - name: Pull and tag as prod env: - REGISTRY: ${{ steps.ecr-login.outputs.registry }} + IMAGE: ghcr.io/innovationtreehouse/arbor-agent SHA: ${{ inputs.sha }} run: | - docker pull $REGISTRY/arbor-agent:$SHA - docker tag $REGISTRY/arbor-agent:$SHA $REGISTRY/arbor-agent:prod - docker push $REGISTRY/arbor-agent:prod - docker pull $REGISTRY/arbor-agent:migrate-$SHA - docker tag $REGISTRY/arbor-agent:migrate-$SHA $REGISTRY/arbor-agent:migrate-prod - docker push $REGISTRY/arbor-agent:migrate-prod + docker pull $IMAGE:$SHA + docker tag $IMAGE:$SHA $IMAGE:prod + docker push $IMAGE:prod + docker pull $IMAGE:migrate-$SHA + docker tag $IMAGE:migrate-$SHA $IMAGE:migrate-prod + docker push $IMAGE:migrate-prod - name: Download Lambda zip from S3 env: @@ -140,7 +139,7 @@ jobs: aws ecs describe-task-definition \ --task-definition arbor-migrate-prod \ --query taskDefinition \ - | jq --arg img "$ACCOUNT.dkr.ecr.$REGION.amazonaws.com/arbor-agent:migrate-$SHA" \ + | jq --arg img "ghcr.io/innovationtreehouse/arbor-agent:migrate-$SHA" \ 'del(.taskDefinitionArn, .revision, .status, .requiresAttributes, .compatibilities, .registeredAt, .registeredBy) | .containerDefinitions[0].image = $img @@ -166,7 +165,7 @@ jobs: --cluster arbor-prod \ --task-definition "${{ steps.register-migrate-task-def-prod.outputs.task_def_arn }}" \ --launch-type FARGATE \ - --network-configuration "awsvpcConfiguration={subnets=[${{ secrets.SUBNET_IDS_PROD }}],securityGroups=[${{ secrets.SECURITY_GROUP_ID_PROD }}],assignPublicIp=DISABLED}" \ + --network-configuration "awsvpcConfiguration={subnets=[${{ secrets.SUBNET_IDS_PROD }}],securityGroups=[${{ secrets.SECURITY_GROUP_ID_PROD }}],assignPublicIp=ENABLED}" \ --overrides "{\"containerOverrides\":[{\"name\":\"arbor-migrate\",\"environment\":[{\"name\":\"DATABASE_URL\",\"value\":\"${{ secrets.DATABASE_URL_PROD }}\"}]}]}" \ --query 'tasks[0].taskArn' --output text) echo "Migration task: $TASK_ARN" @@ -213,7 +212,7 @@ jobs: aws ecs describe-task-definition \ --task-definition arbor-agent-prod \ --query taskDefinition \ - | jq --arg img "$ACCOUNT.dkr.ecr.$REGION.amazonaws.com/arbor-agent:$SHA" \ + | jq --arg img "ghcr.io/innovationtreehouse/arbor-agent:$SHA" \ --arg sha "$SHA" \ --arg tag "$DEPLOY_TAG" \ --arg diff_url "$DIFF_URL" \ diff --git a/packages/lambda/src/index.ts b/packages/lambda/src/index.ts index 3dcd940..73c25ac 100644 --- a/packages/lambda/src/index.ts +++ b/packages/lambda/src/index.ts @@ -194,18 +194,29 @@ async function ensureAgentRunning() { if (listResult.taskArns && listResult.taskArns.length > 0) return; + // Prod runs the agent on the ECS Managed Instances capacity provider with host + // networking (set ECS_CAPACITY_PROVIDER, e.g. "arbor-prod-provider"): no + // launchType/networkConfiguration — egress is via the instance's public IP. + // Dev leaves the var unset and stays on Fargate in awsvpc mode with a public IP. + const capacityProvider = process.env.ECS_CAPACITY_PROVIDER; await ecsClient.send( new RunTaskCommand({ cluster: process.env.ECS_CLUSTER!, taskDefinition: process.env.ECS_TASK_FAMILY!, - launchType: "FARGATE", - networkConfiguration: { - awsvpcConfiguration: { - subnets: process.env.SUBNET_IDS!.split(","), - securityGroups: process.env.SECURITY_GROUP_IDS!.split(","), - assignPublicIp: "ENABLED", - }, - }, + ...(capacityProvider + ? { + capacityProviderStrategy: [{ capacityProvider, weight: 1 }], + } + : { + launchType: "FARGATE", + networkConfiguration: { + awsvpcConfiguration: { + subnets: process.env.SUBNET_IDS!.split(","), + securityGroups: process.env.SECURITY_GROUP_IDS!.split(","), + assignPublicIp: "ENABLED", + }, + }, + }), }) ); }