diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index c420ae6d..00000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,191 +0,0 @@ -name: "Deploy Legacy Frontend" - -run-name: "Deploy `${{ inputs.version }}` to `${{ inputs.environment }}`" - -on: - workflow_dispatch: - inputs: - version: - type: string - required: true - environment: - type: choice - required: true - default: prod - options: - - dev - - prod - run_cluster_tests: - description: 'Run cluster tests for frontend-legacy before deploying' - required: true - type: boolean - default: true - cut_release: - type: boolean - required: true - default: false - description: "Cut the release tag for the `infra` repo. Usually only needed if manually re-deploying a \"Build and Deploy Release\" pipeline that failed." - workflow_call: - inputs: - version: - type: string - required: true - environment: - type: string - required: true - run_cluster_tests: - type: boolean - required: true - cut_release: - type: boolean - required: true - -permissions: - contents: read - issues: none - pull-requests: none - -concurrency: - group: "helium-infra-${{inputs.environment}}" - -jobs: - test: - name: Test Release - if: ${{ inputs.run_cluster_tests }} - - env: - FORCE_COLOR: 1 - PYTHONUNBUFFERED: 1 - PYTHONDONTWRITEBYTECODE: 1 - AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: us-east-1 - PLATFORM_EMAIL_HOST_USER: ${{ secrets.PLATFORM_EMAIL_HOST_USER }} - PLATFORM_EMAIL_HOST_PASSWORD: ${{ secrets.PLATFORM_EMAIL_HOST_PASSWORD }} - PLATFORM_TWILIO_ACCOUNT_SID: ${{ secrets.PLATFORM_TWILIO_ACCOUNT_SID }} - PLATFORM_TWILIO_AUTH_TOKEN: ${{ secrets.PLATFORM_TWILIO_AUTH_TOKEN }} - PLATFORM_TWILIO_SMS_FROM: ${{ vars.PLATFORM_TWILIO_SMS_FROM }} - AWS_INTEGRATION_S3_ACCESS_KEY_ID: ${{ secrets.AWS_INTEGRATION_S3_ACCESS_KEY_ID }} - AWS_INTEGRATION_S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_INTEGRATION_S3_SECRET_ACCESS_KEY }} - CI_TWILIO_RECIPIENT_PHONE_NUMBER: ${{ secrets.CI_TWILIO_RECIPIENT_PHONE_NUMBER }} - - runs-on: ubuntu-latest - - steps: - - name: Generate GitHub App token - id: app-token - uses: actions/create-github-app-token@v3 - with: - client-id: ${{ secrets.HELIUM_BOT_APP_ID }} - private-key: ${{ secrets.HELIUM_BOT_PRIVATE_KEY }} - skip-token-revoke: true - - - uses: actions/checkout@v6 - - - name: Set up Python "3.12" - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - - name: Install GitHub SSH key - uses: shimataro/ssh-key-action@v2 - with: - key: ${{ secrets.SSH_KEY_GITHUB }} - known_hosts: ${{ secrets.KNOWN_HOSTS_GITHUB }} - if_key_exists: replace - - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Get latest platform release version - id: platform_version - uses: HeliumEdu/.github/actions/determine-version@main - with: - token: ${{ steps.app-token.outputs.token }} - repo: platform - - - name: Set container environment variables - env: - PLATFORM_TAG: ${{ steps.platform_version.outputs.version }} - FRONTEND_TAG: ${{ inputs.version }} - FRONTEND_LEGACY_VERSION: ${{ inputs.version }} - run: | - echo "PLATFORM_RESOURCE_IMAGE=public.ecr.aws/heliumedu/helium/platform-resource:amd64-${PLATFORM_TAG}" >> $GITHUB_ENV - echo "PLATFORM_API_IMAGE=public.ecr.aws/heliumedu/helium/platform-api:amd64-${PLATFORM_TAG}" >> $GITHUB_ENV - echo "PLATFORM_WORKER_IMAGE=public.ecr.aws/heliumedu/helium/platform-worker:amd64-${PLATFORM_TAG}" >> $GITHUB_ENV - echo "FRONTEND_LEGACY_VERSION=${FRONTEND_LEGACY_VERSION}" >> $GITHUB_ENV - echo "FRONTEND_IMAGE=public.ecr.aws/heliumedu/helium/frontend:legacy-amd64-${FRONTEND_LEGACY_VERSION}" >> $GITHUB_ENV - - - name: Install dependencies - run: make install - - - name: Run CI tests against release build - uses: nick-fields/retry@v4 - with: - timeout_minutes: 15 - retry_wait_seconds: 15 - max_attempts: 2 - command: make test-cluster-legacy - - - name: Dump Docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v2 - - release: - name: Deploy Legacy Frontend - needs: test - if: always() && (needs.test.result == 'success' || needs.test.result == 'skipped') - - env: - FORCE_COLOR: 1 - PYTHONUNBUFFERED: 1 - PYTHONDONTWRITEBYTECODE: 1 - FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN: ${{ secrets.FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - ENVIRONMENT: ${{ inputs.environment }} - VERSION: ${{ inputs.version }} - - runs-on: ubuntu-latest - - steps: - - name: Generate GitHub App token - id: app-token - uses: actions/create-github-app-token@v3 - with: - client-id: ${{ secrets.HELIUM_BOT_APP_ID }} - private-key: ${{ secrets.HELIUM_BOT_PRIVATE_KEY }} - skip-token-revoke: true - - - uses: actions/checkout@v6 - - - name: Set up Python "3.12" - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - - name: Install dependencies - run: pip install boto3 requests - - - name: Deploy frontend-legacy to S3 - run: python bin/trigger-frontend-legacy-release.py - - - name: Notify Rollbar of frontend deploy - uses: rollbar/github-deploy-action@2.1.2 - with: - environment: ${{ inputs.environment }} - version: ${{ inputs.version }} - env: - ROLLBAR_ACCESS_TOKEN: ${{ secrets.FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN }} - ROLLBAR_USERNAME: ${{ github.actor }} - - - name: Trigger cluster-tests run - run: | - curl -s -X POST https://api.github.com/repos/HeliumEdu/cluster-tests/dispatches \ - -H "Authorization: token ${{ steps.app-token.outputs.token }}" \ - -H "Accept: application/vnd.github+json" \ - -d "{\"event_type\":\"\`frontend-legacy\` triggered for \`${{ inputs.version }}\` to \`${{ inputs.environment }}\`\",\"client_payload\":{\"environment\":\"${{ inputs.environment }}\",\"project\":\"frontend-legacy\",\"version\":\"${{ inputs.version }}\"}}" \ No newline at end of file diff --git a/.github/workflows/release-and-deploy.yml b/.github/workflows/release-and-deploy.yml deleted file mode 100644 index d6f21893..00000000 --- a/.github/workflows/release-and-deploy.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "Release and Deploy Legacy Frontend" - -run-name: "Release and deploy `${{ inputs.version }}` to `${{ inputs.environment }}`" - -on: - workflow_dispatch: - inputs: - version: - type: string - required: true - environment: - type: choice - required: true - default: prod - options: - - dev - - prod - run_cluster_tests: - description: 'Run cluster tests for frontend-legacy before deploying' - required: true - type: boolean - default: true - -jobs: - build: - name: Build - uses: ./.github/workflows/release.yml - secrets: inherit - with: - version: ${{ inputs.version }} - - deploy: - name: Deploy Legacy Frontend - needs: build - uses: ./.github/workflows/deploy.yml - secrets: inherit - with: - version: ${{ inputs.version }} - environment: ${{ inputs.environment }} - run_cluster_tests: ${{ inputs.run_cluster_tests }} - cut_release: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 40bf80d9..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: "Release Legacy Frontend" - -run-name: "Release `${{ inputs.version }}`" - -on: - workflow_dispatch: - inputs: - version: - type: string - required: true - workflow_call: - inputs: - version: - type: string - required: true - -permissions: - contents: read - issues: none - pull-requests: none - -concurrency: - group: helium-infra-release - -jobs: - release: - name: Release Legacy Frontend - - env: - FORCE_COLOR: 1 - PYTHONUNBUFFERED: 1 - PYTHONDONTWRITEBYTECODE: 1 - AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - FRONTEND_ROLLBAR_CLIENT_ITEM_ACCESS_TOKEN: ${{ secrets.FRONTEND_ROLLBAR_CLIENT_ITEM_ACCESS_TOKEN }} - PLATFORM: amd64 - - runs-on: ubuntu-latest - - steps: - - name: Generate GitHub App token - id: app-token - uses: actions/create-github-app-token@v3 - with: - client-id: ${{ secrets.HELIUM_BOT_APP_ID }} - private-key: ${{ secrets.HELIUM_BOT_PRIVATE_KEY }} - skip-token-revoke: true - - - uses: actions/checkout@v6 - - name: Set up Python "3.12" - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - name: Get GitHub App bot user ID - id: get-bot-user-id - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: | - echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" - - name: Setup git - run: | - git config --global user.name "${{ steps.app-token.outputs.app-slug }}[bot]" - git config --global user.email "${{ steps.get-bot-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com" - - name: Install GitHub SSH key - uses: shimataro/ssh-key-action@v2 - with: - key: ${{ secrets.SSH_KEY_GITHUB }} - known_hosts: ${{ secrets.KNOWN_HOSTS_GITHUB }} - if_key_exists: replace - - name: Login to Docker Hub - uses: docker/login-action@v4 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Install dependencies - run: make install - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 - - name: Build frontend-legacy - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - run: TAG_VERSION=${{ inputs.version }} helium-cli build-release ${{ inputs.version }} --projects frontend-legacy - - name: Publish frontend-legacy artifacts - run: TAG_VERSION=${{ inputs.version }} make -C projects/frontend-legacy publish - - name: Dump Docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v2 \ No newline at end of file diff --git a/.heliumcli.yml b/.heliumcli.yml index 355c28ad..03c18055 100644 --- a/.heliumcli.yml +++ b/.heliumcli.yml @@ -10,11 +10,7 @@ projects: - platform - frontend - www -- cluster-tests -- frontend-legacy -releaseProjects: -- cluster-tests -- frontend-legacy +releaseProjects: [] projectsRelativeDir: projects remoteName: origin serverBinFilename: bin/runserver diff --git a/Makefile b/Makefile index 3faac84f..3af0eed5 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,11 @@ -.PHONY: all install-reqs install build start validate test-cluster-legacy fetch-support-articles +.PHONY: all install-reqs install build start validate fetch-support-articles SHELL := /usr/bin/env bash PYTHON_BIN := python -HELIUMCLI_PROJECTS ?= '["platform", "frontend", "www", "cluster-tests", "frontend-legacy"]' +HELIUMCLI_PROJECTS ?= '["platform", "frontend"]' SKIP_UPDATE ?= 'false' DEV_LOCAL_AWS_REGION ?= 'us-east-2' PLATFORM ?= arm64 -PROJECT_APP_LEGACY_HOST ?= http://localhost:3000 all: install start @@ -35,44 +34,8 @@ start: stop: make -C projects/platform stop-docker make -C projects/frontend stop-docker - make -C projects/frontend-legacy stop-docker restart: stop start -start-legacy: - cd projects/frontend-legacy && ./bin/runserver - fetch-support-articles: install-reqs $(PYTHON_BIN) scripts/fetch_support_articles.py - -test-cluster-legacy: - @if [[ -z "${PLATFORM_EMAIL_HOST_USER}" ]] || \ - [[ -z "${PLATFORM_EMAIL_HOST_PASSWORD}" ]] || \ - [[ -z "${PLATFORM_TWILIO_ACCOUNT_SID}" ]] || \ - [[ -z "${PLATFORM_TWILIO_AUTH_TOKEN}" ]] || \ - [[ -z "${PLATFORM_TWILIO_SMS_FROM}" ]] || \ - [[ -z "${AWS_INTEGRATION_S3_ACCESS_KEY_ID}" ]] || \ - [[ -z "${AWS_INTEGRATION_S3_SECRET_ACCESS_KEY}" ]] || \ - [[ -z "${CI_TWILIO_RECIPIENT_PHONE_NUMBER}" ]]; then \ - echo "Set all env vars required to run cluster tests end-to-end against a local Docker build: [\ -PLATFORM_EMAIL_HOST_USER, \ -PLATFORM_EMAIL_HOST_PASSWORD, \ -PLATFORM_TWILIO_ACCOUNT_SID, \ -PLATFORM_TWILIO_AUTH_TOKEN, \ -PLATFORM_TWILIO_SMS_FROM, \ -AWS_INTEGRATION_S3_ACCESS_KEY_ID, \ -AWS_INTEGRATION_S3_SECRET_ACCESS_KEY, \ -CI_TWILIO_RECIPIENT_PHONE_NUMBER]"; \ - exit 1; \ - fi - - ./projects/platform/bin/provision-dot-env.sh - - make -C projects/platform run-docker - make -C projects/frontend-legacy run-docker - - ENVIRONMENT=dev-local \ - PROJECT_APP_HOST=$(PROJECT_APP_LEGACY_HOST) \ - PROJECT_API_HOST=http://localhost:8000 \ - AWS_REGION=$(DEV_LOCAL_AWS_REGION) \ - make -C projects/cluster-tests test diff --git a/bin/trigger-frontend-legacy-release.py b/bin/trigger-frontend-legacy-release.py deleted file mode 100644 index bfc04449..00000000 --- a/bin/trigger-frontend-legacy-release.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python3 - -"""Deploy frontend-legacy static files from artifact S3 bucket to live environment.""" - -import os -import sys - -import boto3 -import requests - -VERSION = os.environ.get("VERSION") -ENVIRONMENT = os.environ.get("ENVIRONMENT") -FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN = os.environ.get("FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN") - -DEPLOY_SOURCE_MAPS = os.environ.get("DEPLOY_SOURCE_MAPS", "true").lower() == "true" -ENVIRONMENT_PREFIX = f'{ENVIRONMENT}.' if 'prod' not in ENVIRONMENT else '' -BASE_URL = f'https://www.{ENVIRONMENT_PREFIX}heliumedu.com' - -if not VERSION or not ENVIRONMENT or not FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN: - print("ERROR: Set all required env vars: VERSION, ENVIRONMENT, FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN.") - sys.exit(1) - -##################################################################### -# Release frontend-legacy code from artifact S3 bucket to live -##################################################################### - -s3 = boto3.resource('s3') -source_bucket_name = "heliumedu" -source_bucket = s3.Bucket(source_bucket_name) -dest_bucket_name = f"heliumedu.{ENVIRONMENT}.frontend.static" -dest_bucket = s3.Bucket(dest_bucket_name) - - -def upload_source_map(minified_url, source_map_key, obj_key): - """Upload source map to Rollbar.""" - s3_client = boto3.client('s3') - - os.makedirs('source_maps', exist_ok=True) - - source_map_path = os.path.join('source_maps', os.path.basename(obj_key)) - s3_client.download_file(source_bucket_name, source_map_key, source_map_path) - with open(source_map_path, 'rb') as f: - data = { - 'access_token': FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN, - 'version': VERSION, - 'minified_url': minified_url, - } - files = { - 'source_map': f - } - - response = requests.post('https://api.rollbar.com/api/1/sourcemap', data=data, files=files) - - print(f"--> Response from {obj_key} source map upload: {response.content}") - - -# Copy assets first, so that new versioned bundles exist before pages are updated -assets_source_prefix = f"helium/frontend-legacy/{VERSION}/assets" -assets_dest_prefix = "assets/" -print(f"Copying frontend-legacy resources from {source_bucket_name}/{assets_source_prefix} to {dest_bucket_name} ...") -for obj in source_bucket.objects.filter(Prefix=assets_source_prefix): - new_key = f"{assets_dest_prefix}" + obj.key[len(assets_source_prefix):].lstrip("/") - - if (obj.key.endswith(".min.js.map") or obj.key.endswith(".min.css.map")) and not DEPLOY_SOURCE_MAPS: - print(f"Skipping file {obj.key}, DEPLOY_SOURCE_MAPS={DEPLOY_SOURCE_MAPS}") - else: - copy_source = { - 'Bucket': source_bucket_name, - 'Key': obj.key - } - dest_bucket.Object(new_key).copy_from(CopySource=copy_source) - print(f"--> '{obj.key}' to '{new_key}'") - - if obj.key.endswith(".min.js.map"): - new_key_url = f"{BASE_URL}/{new_key}" - upload_source_map(new_key_url.removesuffix(".map"), obj.key, obj.key) - -source_prefix = f"helium/frontend-legacy/{VERSION}" -print(f"Copying frontend-legacy resources from {source_bucket_name}/{source_prefix} to {dest_bucket_name} ...") -for obj in source_bucket.objects.filter(Prefix=source_prefix): - # Skip assets, as we've already moved them in to place - if obj.key.startswith(assets_source_prefix): - continue - - new_key = obj.key[len(source_prefix):].lstrip("/") - copy_source = { - 'Bucket': source_bucket_name, - 'Key': obj.key - } - dest_bucket.Object(new_key).copy_from(CopySource=copy_source) - print(f"--> '{obj.key}' to '{new_key}'") - -print(f"... {VERSION} of frontend-legacy is now live in {ENVIRONMENT}.") diff --git a/bin/trigger-release.py b/bin/trigger-release.py deleted file mode 100755 index 0adec6b1..00000000 --- a/bin/trigger-release.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env python - -__copyright__ = "Copyright (c) 2025 Helium Edu" -__license__ = "MIT" - -import json -import os -import re -import sys -import time - -import boto3 -import requests -from git import Repo -from heliumcli import utils -from heliumcli.actions.buildrelease import BuildReleaseAction -from heliumcli.utils import get_config - -BASE_DIR = os.path.normpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')) - -VERSION = os.environ.get("VERSION") -ENVIRONMENT = os.environ.get("ENVIRONMENT") -TERRAFORM_API_TOKEN = os.environ.get("TERRAFORM_API_TOKEN") -FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN = os.environ.get("FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN") - -CUT_RELEASE = os.environ.get("CUT_RELEASE", "true").lower() == "true" -DEPLOY_SOURCE_MAPS = os.environ.get("DEPLOY_SOURCE_MAPS", "false").lower() == "true" -ENVIRONMENT_PREFIX = f'{ENVIRONMENT}.' if 'prod' not in ENVIRONMENT else '' -BASE_URL = f'https://www.{ENVIRONMENT_PREFIX}heliumedu.com' - -if not VERSION or not ENVIRONMENT or not TERRAFORM_API_TOKEN or not FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN or \ - not os.environ.get("AWS_ACCESS_KEY_ID") or not os.environ.get("AWS_SECRET_ACCESS_KEY"): - print( - "ERROR: Set all required env vars: VERSION, ENVIRONMENT, TERRAFORM_API_TOKEN, FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY.") - sys.exit(1) - -INFO_URI = "https://{}.heliumedu.com/info".format("api" if ENVIRONMENT == "prod" else f"api.{ENVIRONMENT}") - -FILE_PATH = os.path.join(BASE_DIR, "terraform", "environments", ENVIRONMENT, "variables.tf") -VERSION_VARIABLE_PATTERN = """variable "helium_version" {{ - description = "The container version. Bumping this will trigger a deploy." - default = "{version}" -}}""" -VERSION_VARIABLE_REGEX = VERSION_VARIABLE_PATTERN.format(version="(\\d+.\\d+.\\d+)") - -##################################################################### -# Bump release version and commit to prep for release deployment -##################################################################### - -if not CUT_RELEASE: - print("CUT_RELEASE is set to 'false'. Deploying old release means no changes committed, and VERSION will be used" - "to set Terraform's 'helium_version' as an override parameter.") -else: - with open(FILE_PATH, "r") as fp: - file_contents = fp.read() - - match = re.match(VERSION_VARIABLE_REGEX, file_contents) - if match: - result = re.sub(VERSION_VARIABLE_REGEX, VERSION_VARIABLE_PATTERN.format(version=VERSION), file_contents) - - if file_contents != result: - with open(FILE_PATH, "w") as fp: - fp.write(result) - else: - print( - "ERROR: variables.tf does not appear to be in the expected format. Ensure the \"helium_version\" variable is " - "defined, with a default, and is the first declaration in the file.") - sys.exit(1) - - repo = Repo(BASE_DIR) - if not repo.is_dirty() or VERSION in repo.tags: - print("ERROR: No changes detected or version already exists. Terraform won't trigger the release. " - "Set CUT_RELEASE=false if attempting to deploy a previous build.") - sys.exit(1) - else: - config = get_config() - - build_release_action = BuildReleaseAction() - print(f"Committing changes and creating release tag {VERSION} ...") - print(utils.get_repo_name(BASE_DIR, config["remoteName"])) - build_release_action._commit_and_tag(BASE_DIR, VERSION, config["remoteName"], config["branchName"]) - - print(f"... release version {VERSION} committed.") - -##################################################################### -# Fetch Terraform Workspace details -##################################################################### - -# TODO: migrate this Terraform deployment code in to `heliumcli`, then it can be removed from infra and platform - -workspaces_response = requests.get(f"https://app.terraform.io/api/v2/organizations/HeliumEdu/workspaces/{ENVIRONMENT}", - headers={"Authorization": f"Bearer {TERRAFORM_API_TOKEN}", - "Content-Type": "application/vnd.api+json"}).json() - -##################################################################### -# Find planned [heliumcli] Terraform run, discard other pending -##################################################################### - -if not CUT_RELEASE: - response = requests.post(f"https://app.terraform.io/api/v2/runs", - headers={"Authorization": f"Bearer {TERRAFORM_API_TOKEN}", - "Content-Type": "application/vnd.api+json"}, - data=json.dumps({"data": - {"attributes": { - "message": f"[heliumcli] Deploy {VERSION}", - "allow-empty-apply": "true", - "auto-apply": "false", - "variables": [ - {"key": "helium_version", "value": f"\"{VERSION}\""} - ] - }, "relationships": { - "workspace": { - "data": { - "id": workspaces_response["data"]["id"], - "type": "workspaces" - } - } - }}}).encode()).json() - -heliumcli_run = None -retries = 0 -retry_sleep_seconds = 10 -wait_minutes = 3 -while retries < ((wait_minutes * 60) / retry_sleep_seconds): - runs_response = requests.get(f"https://app.terraform.io/api/v2/workspaces/{workspaces_response['data']['id']}/runs", - headers={"Authorization": f"Bearer {TERRAFORM_API_TOKEN}", - "Content-Type": "application/vnd.api+json"}).json() - - for run in runs_response["data"]: - # Discard all planned or pending plans that are not what was just triggered by [heliumcli] for this version - if (run["attributes"]["status"] in ["planned", "pending"] and - (not run["attributes"]["message"].startswith("[heliumcli]") or VERSION not in run["attributes"][ - "message"])): - reject_endpoint = "cancel" if run["attributes"]["actions"]["is-cancelable"] else "discard" - requests.post(f"https://app.terraform.io/api/v2/runs/{run['id']}/actions/{reject_endpoint}", - headers={"Authorization": f"Bearer {TERRAFORM_API_TOKEN}", - "Content-Type": "application/vnd.api+json"}, - data=json.dumps( - {"comment": "Discarding plan in favor of official release plan"}).encode()) - # Continue to wait until the [heliumcli] plan is in the correct state - elif (run["attributes"]["status"] == "planned" and - run["attributes"]["message"].startswith("[heliumcli]") and - VERSION in run["attributes"]["message"]): - print(f"... found planned [heliumcli] run for {VERSION} with ID {run['id']}.") - heliumcli_run = run - break - - if heliumcli_run: - break - else: - retries += 1 - print("Waiting for Terraform ...") - time.sleep(retry_sleep_seconds) - -if not heliumcli_run: - print("ERROR: [heliumcli] plan was never found in Terraform.") - sys.exit(1) - -##################################################################### -# Trigger Terraform apply for release -##################################################################### - -print(f"Triggering Terraform apply on run ID {heliumcli_run['id']} in {ENVIRONMENT} ...") -resp = requests.post(f"https://app.terraform.io/api/v2/runs/{heliumcli_run['id']}/actions/apply", - headers={"Authorization": f"Bearer {TERRAFORM_API_TOKEN}", - "Content-Type": "application/vnd.api+json"}, - data=json.dumps({"comments": f"[heliumcli] Apply {VERSION}"}).encode()).json() - -##################################################################### -# Release frontend code from artifact S3 bucket to live -##################################################################### - -s3 = boto3.resource('s3') -source_bucket_name = "heliumedu" -source_bucket = s3.Bucket(source_bucket_name) -dest_bucket_name = f"heliumedu.{ENVIRONMENT}.frontend.static" -dest_bucket = s3.Bucket(dest_bucket_name) - - -def upload_source_map(minified_url, source_map_key): - s3_client = boto3.client('s3') - - os.makedirs('source_maps', exist_ok=True) - - source_map_path = os.path.join('source_maps', os.path.basename(obj.key)) - s3_client.download_file(source_bucket_name, source_map_key, source_map_path) - with open(source_map_path, 'rb') as f: - data = { - 'access_token': FRONTEND_ROLLBAR_SERVER_ITEM_ACCESS_TOKEN, - 'version': VERSION, - 'minified_url': minified_url, - } - files = { - 'source_map': f - } - - response = requests.post('https://api.rollbar.com/api/1/sourcemap', data=data, files=files) - - print(f"--> Response from {obj.key} source map upload: {response.content}") - -# Copy assets first, so that new versioned bundles exist before pages are updated - -assets_source_prefix = f"helium/frontend-legacy/{VERSION}/assets" -assets_dest_prefix = "assets/" -print(f"Copying frontend-legacy resources from {source_bucket_name}{assets_source_prefix} to {dest_bucket_name} ...") -for obj in source_bucket.objects.filter(Prefix=assets_source_prefix): - new_key = f"{assets_dest_prefix}" + obj.key[len(assets_source_prefix):].lstrip("/") - - if (obj.key.endswith(".min.js.map") or obj.key.endswith(".min.css.map")) and not DEPLOY_SOURCE_MAPS: - print(f"Skipping file {obj.key}, DEPLOY_SOURCE_MAPS={DEPLOY_SOURCE_MAPS}") - else: - copy_source = { - 'Bucket': source_bucket_name, - 'Key': obj.key - } - dest_bucket.Object(new_key).copy_from(CopySource=copy_source) - print(f"--> '{obj.key}' to '{new_key}'") - - if obj.key.endswith(".min.js.map"): - new_key_url = f"{BASE_URL}/{new_key}" - upload_source_map(new_key_url.removesuffix(".map"), obj.key) - -source_prefix = f"helium/frontend-legacy/{VERSION}" -print(f"Copying frontend-legacy resources from {source_bucket_name}{source_prefix} to {dest_bucket_name} ...") -for obj in source_bucket.objects.filter(Prefix=source_prefix): - # Skip assets, as we've already moved them in to place - if obj.key.startswith(assets_source_prefix): - continue - - new_key = obj.key[len(source_prefix):].lstrip("/") - copy_source = { - 'Bucket': source_bucket_name, - 'Key': obj.key - } - dest_bucket.Object(new_key).copy_from(CopySource=copy_source) - print(f"--> '{obj.key}' to '{new_key}'") - -print(f"... {VERSION} of the frontend-legacy is now live in {ENVIRONMENT}.") - -##################################################################### -# Wait for the Terraform apply to be live -##################################################################### - -version_is_live = False -retries = 0 -retry_sleep_seconds = 20 -wait_minutes = 10 -while retries < ((wait_minutes * 60) / retry_sleep_seconds): - result = requests.get(INFO_URI).json() - if result["version"] == VERSION: - version_is_live = True - break - else: - retries += 1 - print(f"Waiting for {ENVIRONMENT} to report version {VERSION} ...") - time.sleep(retry_sleep_seconds) - -if version_is_live: - print(f"... {VERSION} is now live in {ENVIRONMENT}.") -else: - print( - f"ERROR: {ENVIRONMENT} has not updated its version number to {VERSION} within {wait_minutes} minutes, " - "check if deploy failed.") - sys.exit(1) diff --git a/requirements.txt b/requirements.txt index 24606645..d4467539 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,3 @@ heliumcli==1.6.38 -boto3==1.42.73 -requests==2.33.0 beautifulsoup4==4.13.4 html2text==2024.2.26 \ No newline at end of file diff --git a/terraform/environments/dev-local/main.tf b/terraform/environments/dev-local/main.tf index 4f083827..2b658e35 100644 --- a/terraform/environments/dev-local/main.tf +++ b/terraform/environments/dev-local/main.tf @@ -54,13 +54,3 @@ module "secretsmanager" { integration_s3_access_key_id = module.s3.access_key_id integration_s3_secret_access_key = module.s3.secret_access_key } - -module "twilio" { - source = "../../modules/environment/twilio" - - environment = var.environment - helium_twiml_handler_url = var.HELIUM_TWIML_HANDLER_URL - ci_twiml_handler_url = var.CI_TWIML_HANDLER_URL - helium_area_code = var.helium_area_code - ci_area_code = var.ci_area_code -} diff --git a/terraform/environments/dev-local/variables.tf b/terraform/environments/dev-local/variables.tf index c0891ded..c30abf8b 100644 --- a/terraform/environments/dev-local/variables.tf +++ b/terraform/environments/dev-local/variables.tf @@ -13,16 +13,6 @@ variable "aws_region" { default = "us-east-2" } -variable "helium_area_code" { - description = "The area code for the Helium phone number" - default = "815" -} - -variable "ci_area_code" { - description = "The area code for the CI test phone number" - default = "815" -} - variable "heliumedu_com_zone_id" { description = "For non-prod zones, this is used to link the env's subdomain in the parent domain" } @@ -51,20 +41,3 @@ variable "AWS_SECRET_ACCESS_KEY" { sensitive = true } -variable "TWILIO_ACCOUNT_SID" { - description = "The Twilio account SID" - sensitive = true -} - -variable "TWILIO_AUTH_TOKEN" { - description = "The Twilio auth token" - sensitive = true -} - -variable "HELIUM_TWIML_HANDLER_URL" { - description = "The URL for the Helium TwiML Bin" -} - -variable "CI_TWIML_HANDLER_URL" { - description = "The URL for the CI TwiML Bin" -} \ No newline at end of file diff --git a/terraform/environments/dev/main.tf b/terraform/environments/dev/main.tf index e0e28ff0..8020b379 100644 --- a/terraform/environments/dev/main.tf +++ b/terraform/environments/dev/main.tf @@ -117,8 +117,6 @@ module "cloudfront" { environment = var.environment environment_prefix = var.environment_prefix - s3_bucket = module.s3.heliumedu_s3_frontend_bucket_name - s3_website_endpoint = module.s3.heliumedu_s3_website_endpoint s3_frontend_app_bucket = module.s3.heliumedu_s3_frontend_app_bucket_name s3_frontend_app_website_endpoint = module.s3.heliumedu_s3_frontend_app_website_endpoint heliumedu_com_cert_arn = module.certificatemanager.heliumedu_com_cert_arn @@ -158,9 +156,6 @@ module "secretsmanager" { s3_user_secret_access_key = module.s3.s3_access_key_secret smtp_email_user = module.ses.smtp_username smtp_email_password = module.ses.smtp_password - twilio_account_sid = var.TWILIO_ACCOUNT_SID - twilio_auth_token = var.TWILIO_AUTH_TOKEN - twilio_phone_number = module.twilio.helium_phone_number firebase_project_id = var.FIREBASE_PROJECT_ID firebase_private_key_id = var.FIREBASE_PRIVATE_KEY_ID firebase_private_key = var.FIREBASE_PRIVATE_KEY @@ -170,13 +165,3 @@ module "secretsmanager" { ga4_measurement_id = var.GA4_MEASUREMENT_ID ga4_api_secret = var.GA4_API_SECRET } - -module "twilio" { - source = "../../modules/environment/twilio" - - environment = var.environment - helium_area_code = var.helium_area_code - ci_area_code = var.ci_area_code - helium_twiml_handler_url = var.HELIUM_TWIML_HANDLER_URL - ci_twiml_handler_url = var.CI_TWIML_HANDLER_URL -} diff --git a/terraform/environments/dev/variables.tf b/terraform/environments/dev/variables.tf index b658c4a6..7b096d9f 100644 --- a/terraform/environments/dev/variables.tf +++ b/terraform/environments/dev/variables.tf @@ -82,16 +82,6 @@ variable "request_timeout_seconds" { default = 60 } -variable "helium_area_code" { - description = "The area code for the Helium phone number" - default = "320" -} - -variable "ci_area_code" { - description = "The area code for the CI phone number" - default = "320" -} - variable "platform_resource_repository_uri" { default = "public.ecr.aws/heliumedu/helium/platform-resource" } @@ -124,24 +114,6 @@ variable "AWS_SECRET_ACCESS_KEY" { sensitive = true } -variable "TWILIO_ACCOUNT_SID" { - description = "The Twilio account SID" - sensitive = true -} - -variable "TWILIO_AUTH_TOKEN" { - description = "The Twilio auth token" - sensitive = true -} - -variable "HELIUM_TWIML_HANDLER_URL" { - description = "The URL for the Helium TwiML Bin" -} - -variable "CI_TWIML_HANDLER_URL" { - description = "The URL for the CI TwiML Bin" -} - variable "DD_API_KEY" { description = "The DataDog API key" sensitive = true diff --git a/terraform/environments/prod/README.md b/terraform/environments/prod/README.md index 4b6b768e..68a2398b 100644 --- a/terraform/environments/prod/README.md +++ b/terraform/environments/prod/README.md @@ -5,29 +5,6 @@ The following services are setup in a `prod`-like environment: - [AWS](https://aws.amazon.com/) - hosting infrastructure, attachments, and emails - [DataDog](https://www.datadoghq.com/) - (optional, infrastructure monitoring) - [Sentry](https://rollbar.com/) - (optional, real-time error logging and tracking) -- [Twilio](https://www.twilio.com/en-us) - (optional, text messages, deprecating in favor of Push on new frontend) - -### Twilio Setup - -Not all Twilio operations can be provisioned with Terraform. Manually create two TwiML Bins via [the Twilio Console](https://www.twilio.com/console): - -**Helium Auto Response** -```xml - - - This number is only for sending notifications and is not monitored. - -``` - -**CI Empty Ack** -```xml - - -``` - -Note the URLs for these TwiML Bins, they need to be stored in the Terraform Workspace next. - -Additionally, after the Terraform has been applied and the Twilio numbers exist, the `Helium Edu` number won't be able to send outbound text messages until they've gone through the A2P 10DLC registration process, which also must be done [in the Twilio Console](https://console.twilio.com/us1/develop/sms/regulatory-compliance/a2p-10dlc-overview). ### Initializing a Terraform Workspace @@ -45,10 +22,6 @@ The following Terraform Workspace variables must be defined: - `AWS_SECRET_ACCESS_KEY` - `DD_API_KEY` (the DataDog API key, leave blank to disable) - `SENTRY_DSN` (the Platform Sentry DSN, leave blank to disable) - - `TWILIO_ACCOUNT_SID` (optional if Twilio module is removed) - - `TWILIO_AUTH_TOKEN` (optional if Twilio module is removed) - - `HELIUM_TWIML_HANDLER_URL` (optional if Twilio module is removed) - - `CI_TWIML_HANDLER_URL` (optional if Twilio module is removed) Once all of the above is configured, you can trigger Terraform to provision the new environment by executing: diff --git a/terraform/environments/prod/main.tf b/terraform/environments/prod/main.tf index 5cef5889..3d4e3f75 100644 --- a/terraform/environments/prod/main.tf +++ b/terraform/environments/prod/main.tf @@ -110,8 +110,6 @@ module "cloudfront" { environment = var.environment environment_prefix = var.environment_prefix - s3_bucket = module.s3.heliumedu_s3_frontend_bucket_name - s3_website_endpoint = module.s3.heliumedu_s3_website_endpoint s3_frontend_app_bucket = module.s3.heliumedu_s3_frontend_app_bucket_name s3_frontend_app_website_endpoint = module.s3.heliumedu_s3_frontend_app_website_endpoint s3_ci_frontend_app_website_endpoint = module.s3.heliumedu_ci_s3_frontend_app_website_endpoint @@ -153,9 +151,6 @@ module "secretsmanager" { smtp_email_user = module.ses.smtp_username smtp_email_password = module.ses.smtp_password ci_app_host = module.cloudfront.ci_frontend_app_cloudfront_domain_name - twilio_account_sid = var.TWILIO_ACCOUNT_SID - twilio_auth_token = var.TWILIO_AUTH_TOKEN - twilio_phone_number = module.twilio.helium_phone_number firebase_project_id = var.FIREBASE_PROJECT_ID firebase_private_key_id = var.FIREBASE_PRIVATE_KEY_ID firebase_private_key = var.FIREBASE_PRIVATE_KEY @@ -165,13 +160,3 @@ module "secretsmanager" { ga4_measurement_id = var.GA4_MEASUREMENT_ID ga4_api_secret = var.GA4_API_SECRET } - -module "twilio" { - source = "../../modules/environment/twilio" - - environment = var.environment - helium_area_code = var.helium_area_code - ci_area_code = var.ci_area_code - helium_twiml_handler_url = var.HELIUM_TWIML_HANDLER_URL - ci_twiml_handler_url = var.CI_TWIML_HANDLER_URL -} diff --git a/terraform/environments/prod/variables.tf b/terraform/environments/prod/variables.tf index 218b9876..40bfe3d9 100644 --- a/terraform/environments/prod/variables.tf +++ b/terraform/environments/prod/variables.tf @@ -76,16 +76,6 @@ variable "request_timeout_seconds" { default = 60 } -variable "helium_area_code" { - description = "The area code for the Helium phone number" - default = "650" -} - -variable "ci_area_code" { - description = "The area code for the CI phone number" - default = "650" -} - ### Variables defined below this point must have their defaults defined in the Terraform Workspace variable "AWS_ACCESS_KEY_ID" { @@ -98,24 +88,6 @@ variable "AWS_SECRET_ACCESS_KEY" { sensitive = true } -variable "TWILIO_ACCOUNT_SID" { - description = "The Twilio account SID" - sensitive = true -} - -variable "TWILIO_AUTH_TOKEN" { - description = "The Twilio auth token" - sensitive = true -} - -variable "HELIUM_TWIML_HANDLER_URL" { - description = "The URL for the Helium TwiML Bin" -} - -variable "CI_TWIML_HANDLER_URL" { - description = "The URL for the CI TwiML Bin" -} - variable "DD_API_KEY" { description = "The DataDog API key" sensitive = true diff --git a/terraform/modules/environment/cloudfront/main.tf b/terraform/modules/environment/cloudfront/main.tf index 12063120..294cc090 100644 --- a/terraform/modules/environment/cloudfront/main.tf +++ b/terraform/modules/environment/cloudfront/main.tf @@ -1,10 +1,3 @@ -resource "aws_cloudfront_function" "rewrites" { - name = "${var.environment}-rewrites" - runtime = "cloudfront-js-2.0" - publish = true - code = file("${path.module}/rewrites.js") -} - resource "aws_cloudfront_function" "rewrites_spa" { name = "${var.environment}-rewrites-spa" runtime = "cloudfront-js-2.0" @@ -12,86 +5,6 @@ resource "aws_cloudfront_function" "rewrites_spa" { code = file("${path.module}/rewrites-spa.js") } -resource "aws_cloudfront_distribution" "heliumedu_frontend" { - enabled = true - aliases = ["www.${var.route53_heliumedu_com_zone_name}"] - comment = "www.${var.route53_heliumedu_com_zone_name}" - default_root_object = "index.html" - price_class = "PriceClass_100" - - origin { - origin_id = "${var.s3_bucket}-origin" - domain_name = var.s3_website_endpoint - custom_origin_config { - http_port = 80 - https_port = 443 - origin_protocol_policy = "http-only" - origin_ssl_protocols = ["TLSv1"] - } - } - - default_cache_behavior { - target_origin_id = "${var.s3_bucket}-origin" - allowed_methods = ["GET", "HEAD"] - cached_methods = ["GET", "HEAD"] - - forwarded_values { - query_string = true - - cookies { - forward = "all" - } - } - - viewer_protocol_policy = "redirect-to-https" - default_ttl = 3600 - min_ttl = 300 - max_ttl = 86400 - - function_association { - event_type = "viewer-request" - function_arn = aws_cloudfront_function.rewrites.arn - } - } - - custom_error_response { - error_code = 404 - response_code = 404 - response_page_path = "/404.html" - } - - custom_error_response { - error_code = 500 - response_code = 500 - response_page_path = "/500.html" - } - - viewer_certificate { - cloudfront_default_certificate = false - acm_certificate_arn = var.heliumedu_com_cert_arn - ssl_support_method = "sni-only" - minimum_protocol_version = "TLSv1.2_2021" - } - - restrictions { - geo_restriction { - restriction_type = "none" - } - } -} - -resource "aws_route53_record" "www_heliumedu_com" { - zone_id = var.route53_heliumedu_com_zone_id - name = "www.${var.route53_heliumedu_com_zone_name}" - type = "A" - - alias { - name = aws_cloudfront_distribution.heliumedu_frontend.domain_name - zone_id = aws_cloudfront_distribution.heliumedu_frontend.hosted_zone_id - evaluate_target_health = false - } -} - resource "aws_s3_bucket" "heliumedu_frontend_non_www" { bucket = "heliumedu.${var.environment}.frontend.non-www-redirect" } diff --git a/terraform/modules/environment/cloudfront/outputs.tf b/terraform/modules/environment/cloudfront/outputs.tf index 46653a96..f3d556be 100644 --- a/terraform/modules/environment/cloudfront/outputs.tf +++ b/terraform/modules/environment/cloudfront/outputs.tf @@ -1,7 +1,3 @@ -output "cloudfront_domain_name" { - value = aws_cloudfront_distribution.heliumedu_frontend.domain_name -} - output "ci_frontend_app_cloudfront_domain_name" { value = length(aws_cloudfront_distribution.heliumedu_ci_frontend_app) > 0 ? aws_cloudfront_distribution.heliumedu_ci_frontend_app[0].domain_name : null } diff --git a/terraform/modules/environment/cloudfront/rewrites.js b/terraform/modules/environment/cloudfront/rewrites.js deleted file mode 100644 index 926fe9e5..00000000 --- a/terraform/modules/environment/cloudfront/rewrites.js +++ /dev/null @@ -1,133 +0,0 @@ -function handler(event) { - var request = event.request; - var uri = request.uri; - - // Shared static assets (SEO, favicon, social card, app association files) - // used to be served by the legacy frontend at www.heliumedu.com. They now - // live on landing.heliumedu.com (the new marketing site) — redirect so - // crawlers, browsers, social platforms, and the iOS/Android apps don't - // 404 during the legacy-shutdown window. After the Aug 1 cutover (when - // www becomes the marketing site directly), this whole function is - // deleted in phase 1. - var sharedAssetRedirects = { - '/sitemap.xml': 'https://landing.heliumedu.com/sitemap.xml', - '/sitemap-index.xml': 'https://landing.heliumedu.com/sitemap-index.xml', - '/sitemap-0.xml': 'https://landing.heliumedu.com/sitemap-0.xml', - '/robots.txt': 'https://landing.heliumedu.com/robots.txt', - '/favicon.ico': 'https://landing.heliumedu.com/favicon.ico', - '/favicon.png': 'https://landing.heliumedu.com/favicon.png', - '/img/og-default.png': 'https://landing.heliumedu.com/img/og-default.png', - '/img/helium-logo.png': 'https://landing.heliumedu.com/img/helium-logo.png', - '/img/helium-logo-square.png': 'https://landing.heliumedu.com/img/helium-logo-square.png', - '/img/support-patreon.svg': 'https://landing.heliumedu.com/img/support-patreon.svg', - '/img/support-patreon.png': 'https://landing.heliumedu.com/img/support-patreon.png', - '/.well-known/apple-app-site-association': 'https://landing.heliumedu.com/.well-known/apple-app-site-association', - '/.well-known/assetlinks.json': 'https://landing.heliumedu.com/.well-known/assetlinks.json' - }; - if (sharedAssetRedirects[uri] !== undefined) { - return { - statusCode: 301, - statusDescription: 'Moved Permanently', - headers: { - 'location': { - 'value': sharedAssetRedirects[uri] - } - } - }; - } - - var normalized = uri; - if (normalized.length > 1 && normalized.endsWith('/')) { - normalized = normalized.slice(0, -1); - } - if (normalized.endsWith('.html')) { - normalized = normalized.slice(0, -5); - } - - var landingPath = { - '/': '/', - '/index': '/', - '/about': '/about', - '/terms': '/terms', - '/privacy': '/privacy', - '/press': '/press' - }; - if (landingPath[normalized] !== undefined) { - return { - statusCode: 301, - statusDescription: 'Moved Permanently', - headers: { - 'location': { - 'value': 'https://landing.heliumedu.com' + landingPath[normalized] - } - } - }; - } - - // Bridge: all /support* paths on legacy www → landing (where the new portal - // actually lives until the Aug 1 cutover). Target MUST be landing here, not - // www.heliumedu.com/support — pointing back at the same host would loop. - if (normalized === '/support' || normalized.startsWith('/support/')) { - return { - statusCode: 301, - statusDescription: 'Moved Permanently', - headers: { - 'location': { - 'value': 'https://landing.heliumedu.com' + normalized - } - } - }; - } - - // /contact points at the canonical www.heliumedu.com/support/submit URL - // (the branded ticket form). During the legacy period, the bridge rule - // above catches the follow-up request and forwards to landing. At cutover, - // this becomes a single 301 to the live www marketing site without any - // further edits. - if (normalized === '/contact') { - return { - statusCode: 301, - statusDescription: 'Moved Permanently', - headers: { - 'location': { - 'value': 'https://www.heliumedu.com/support/submit' - } - } - }; - } - - if (normalized === '/docs') { - return { - statusCode: 301, - statusDescription: 'Moved Permanently', - headers: { - 'location': { - 'value': 'https://api.heliumedu.com/docs' - } - } - }; - } - - if (uri.endsWith('.html')) { - var newUri = uri.slice(0, -5); - return { - statusCode: 301, - statusDescription: 'Moved Permanently', - headers: { - 'location': { - 'value': newUri - } - } - }; - } - - if (uri === '/info') { - request.uri = '/assets/info.json'; - } else if (!uri.includes('.') && !uri.endsWith('/')) { - request.uri += '.html'; - } else if (uri.endsWith('/')) { - request.uri += 'index.html'; - } - - return request; -} diff --git a/terraform/modules/environment/cloudfront/variables.tf b/terraform/modules/environment/cloudfront/variables.tf index 144a30cb..f0f3af15 100644 --- a/terraform/modules/environment/cloudfront/variables.tf +++ b/terraform/modules/environment/cloudfront/variables.tf @@ -18,15 +18,6 @@ variable "heliumstudy_com_cert_arn" { type = string } -variable "s3_bucket" { - description = "The S3 bucket to host" - type = string -} - -variable "s3_website_endpoint" { - default = "The endpoint for the S3 site" -} - variable "s3_frontend_app_bucket" { description = "The S3 bucket for the Flutter app frontend" type = string diff --git a/terraform/modules/environment/ecr/main.tf b/terraform/modules/environment/ecr/main.tf index d4100055..ddbf72b2 100644 --- a/terraform/modules/environment/ecr/main.tf +++ b/terraform/modules/environment/ecr/main.tf @@ -3,24 +3,6 @@ locals { platform_usage_text = "Helium is open source, and usage details for this image be found at https://github.com/heliumedu/platform." } -resource "aws_ecrpublic_repository" "repository_helium_frontend" { - repository_name = "helium/frontend" - - catalog_data { - operating_systems = ["Linux"] - architectures = ["x86-64", "ARM 64"] - logo_image_blob = filebase64("${path.module}/../../../resources/logo.png") - description = "Images for the frontend-legacy containers." - about_text = local.about_text - usage_text = "HeliumEdu is open source, and usage details for this image be found at https://github.com/heliumedu/frontend-legacy." - } - - tags = { - Environment = "N/A" - Service = "HeliumEdu" - } -} - resource "aws_ecrpublic_repository" "repository_helium_frontend_web" { repository_name = "helium/frontend-web" diff --git a/terraform/modules/environment/ecr/outputs.tf b/terraform/modules/environment/ecr/outputs.tf index d70b4a9d..2fd78b57 100644 --- a/terraform/modules/environment/ecr/outputs.tf +++ b/terraform/modules/environment/ecr/outputs.tf @@ -1,7 +1,3 @@ -output "frontend_repository_uri" { - value = aws_ecrpublic_repository.repository_helium_frontend.repository_uri -} - output "frontend_web_repository_uri" { value = aws_ecrpublic_repository.repository_helium_frontend_web.repository_uri } diff --git a/terraform/modules/environment/s3/main.tf b/terraform/modules/environment/s3/main.tf index 914eacd9..9262294a 100644 --- a/terraform/modules/environment/s3/main.tf +++ b/terraform/modules/environment/s3/main.tf @@ -90,67 +90,6 @@ resource "aws_s3_bucket_cors_configuration" "heliumedu_platform_static" { } } -resource "aws_s3_bucket" "heliumedu_frontend_static" { - bucket = "heliumedu.${var.environment}.frontend.static" -} - -resource "aws_s3_bucket_public_access_block" "heliumedu_frontend_static_allow_public" { - bucket = aws_s3_bucket.heliumedu_frontend_static.id - - block_public_acls = false - block_public_policy = false - ignore_public_acls = false - restrict_public_buckets = false -} - -data "aws_iam_policy_document" "heliumedu_frontend_static_allow_http_access" { - statement { - principals { - type = "*" - identifiers = ["*"] - } - - resources = [ - "arn:aws:s3:::heliumedu.${var.environment}.frontend.static/**", - ] - - actions = [ - "s3:GetObject" - ] - } -} - -resource "aws_s3_bucket_policy" "heliumedu_frontend_static_allow_http_access" { - bucket = aws_s3_bucket.heliumedu_frontend_static.id - policy = data.aws_iam_policy_document.heliumedu_frontend_static_allow_http_access.json - - depends_on = [aws_s3_bucket_public_access_block.heliumedu_frontend_static_allow_public] -} - -resource "aws_s3_bucket_cors_configuration" "heliumedu_frontend_static" { - bucket = aws_s3_bucket.heliumedu_frontend_static.id - - cors_rule { - allowed_headers = ["*"] - allowed_methods = ["GET", "HEAD"] - allowed_origins = ["*"] - expose_headers = ["ETag"] - max_age_seconds = 3000 - } -} - -resource "aws_s3_bucket_website_configuration" "heliumedu_frontend" { - bucket = aws_s3_bucket.heliumedu_frontend_static.id - - index_document { - suffix = "index.html" - } - - error_document { - key = "404.html" - } -} - // Flutter app frontend bucket (app.heliumedu.com) resource "aws_s3_bucket" "heliumedu_frontend_app_static" { @@ -267,29 +206,6 @@ resource "aws_s3_bucket_lifecycle_configuration" "helium_alb_logs_lifecycle" { } } -// Buckets only created once, for production - -resource "aws_s3_bucket" "heliumedu" { - count = var.environment == "prod" ? 1 : 0 - - bucket = "heliumedu" - - tags = { - Environment = "N/A" - } -} - -resource "aws_s3_bucket_public_access_block" "heliumedu_block_public" { - count = var.environment == "prod" ? 1 : 0 - - bucket = aws_s3_bucket.heliumedu[0].id - - block_public_acls = true - block_public_policy = true - ignore_public_acls = true - restrict_public_buckets = true -} - // CI preview bucket resource "aws_s3_bucket" "heliumedu_ci_frontend_app_static" { diff --git a/terraform/modules/environment/s3/outputs.tf b/terraform/modules/environment/s3/outputs.tf index 9b01ccac..c5f9ecea 100644 --- a/terraform/modules/environment/s3/outputs.tf +++ b/terraform/modules/environment/s3/outputs.tf @@ -9,14 +9,6 @@ output "s3_access_key_secret" { value = aws_iam_access_key.s3_access_key.secret } -output "heliumedu_s3_frontend_bucket_name" { - value = aws_s3_bucket.heliumedu_frontend_static.bucket -} - -output "heliumedu_s3_website_endpoint" { - value = aws_s3_bucket_website_configuration.heliumedu_frontend.website_endpoint -} - output "heliumedu_s3_frontend_app_bucket_name" { value = aws_s3_bucket.heliumedu_frontend_app_static.bucket } diff --git a/terraform/modules/environment/secretsmanager/main.tf b/terraform/modules/environment/secretsmanager/main.tf index 022356a3..6ce7fda6 100644 --- a/terraform/modules/environment/secretsmanager/main.tf +++ b/terraform/modules/environment/secretsmanager/main.tf @@ -32,9 +32,6 @@ resource "aws_secretsmanager_secret_version" "helium_secret_version" { { PLATFORM_EMAIL_HOST_USER = var.smtp_email_user PLATFORM_EMAIL_HOST_PASSWORD = var.smtp_email_password - PLATFORM_TWILIO_ACCOUNT_SID = var.twilio_account_sid - PLATFORM_TWILIO_AUTH_TOKEN = var.twilio_auth_token - PLATFORM_TWILIO_SMS_FROM = var.twilio_phone_number PLATFORM_AWS_S3_ACCESS_KEY_ID = var.s3_user_access_key_id PLATFORM_AWS_S3_SECRET_ACCESS_KEY = var.s3_user_secret_access_key PLATFORM_REDIS_HOST = "redis://${var.redis_host}" diff --git a/terraform/modules/environment/secretsmanager/variables.tf b/terraform/modules/environment/secretsmanager/variables.tf index fcb30420..0a522052 100644 --- a/terraform/modules/environment/secretsmanager/variables.tf +++ b/terraform/modules/environment/secretsmanager/variables.tf @@ -28,18 +28,6 @@ variable "smtp_email_password" { type = string } -variable "twilio_account_sid" { - type = string -} - -variable "twilio_auth_token" { - type = string -} - -variable "twilio_phone_number" { - type = string -} - variable "s3_user_access_key_id" { type = string } diff --git a/terraform/modules/environment/twilio/backend.tf b/terraform/modules/environment/twilio/backend.tf deleted file mode 100644 index ffd173fc..00000000 --- a/terraform/modules/environment/twilio/backend.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_providers { - twilio = { - source = "twilio/twilio" - version = "0.18.46" - } - } - - required_version = ">= 1.5.0" -} \ No newline at end of file diff --git a/terraform/modules/environment/twilio/main.tf b/terraform/modules/environment/twilio/main.tf deleted file mode 100644 index 7690ac3f..00000000 --- a/terraform/modules/environment/twilio/main.tf +++ /dev/null @@ -1,13 +0,0 @@ -resource "twilio_api_accounts_incoming_phone_numbers" "helium_phone_number" { - friendly_name = "Helium Edu (${var.environment})" - sms_url = var.helium_twiml_handler_url - voice_url = "" - area_code = var.helium_area_code -} - -resource "twilio_api_accounts_incoming_phone_numbers" "ci_phone_number" { - friendly_name = "CI Test Number (${var.environment})" - sms_url = var.ci_twiml_handler_url - voice_url = "" - area_code = var.ci_area_code -} diff --git a/terraform/modules/environment/twilio/outputs.tf b/terraform/modules/environment/twilio/outputs.tf deleted file mode 100644 index 13eccad5..00000000 --- a/terraform/modules/environment/twilio/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -output "helium_phone_number" { - value = twilio_api_accounts_incoming_phone_numbers.helium_phone_number.phone_number -} - -output "ci_phone_number" { - value = twilio_api_accounts_incoming_phone_numbers.ci_phone_number.phone_number -} \ No newline at end of file diff --git a/terraform/modules/environment/twilio/variables.tf b/terraform/modules/environment/twilio/variables.tf deleted file mode 100644 index eed4285c..00000000 --- a/terraform/modules/environment/twilio/variables.tf +++ /dev/null @@ -1,24 +0,0 @@ -variable "environment" { - description = "The environment" - type = string -} - -variable "helium_area_code" { - description = "The area code for the Helium phone number" - type = string -} - -variable "ci_area_code" { - description = "The area code for the CI phone number" - type = string -} - -variable "helium_twiml_handler_url" { - description = "The URL for the TwiML Bin" - type = string -} - -variable "ci_twiml_handler_url" { - description = "The URL for the TwiML Bin" - type = string -} \ No newline at end of file