Deploy HydroServer to AWS Cloud Deployment #107
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Deploy HydroServer to AWS Cloud Deployment | |
on: | |
workflow_dispatch: | |
inputs: | |
environment: | |
description: 'Enter a deployment environment name.' | |
required: true | |
hydroserver-version: | |
description: 'Enter a version of HydroServer to use. Leave blank to use the latest version.' | |
required: false | |
permissions: | |
id-token: write | |
contents: read | |
jobs: | |
deploy-backend: | |
name: Deploy Backend | |
runs-on: ubuntu-latest | |
environment: ${{ github.event.inputs.environment }} | |
steps: | |
- name: configureawscredentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_IAM_ROLE }} | |
role-session-name: create-hydroserver-resources | |
aws-region: ${{ vars.AWS_REGION }} | |
- name: Get Latest HydroServer Version | |
id: get_latest_tag | |
run: echo "tag=$(curl -sL https://api.github.com/repos/hydroserver2/hydroserver-api-services/releases/latest | jq -r '.tag_name')" >> $GITHUB_OUTPUT | |
- name: Checkout Backend Repo | |
uses: actions/checkout@v4 | |
with: | |
repository: hydroserver2/hydroserver-api-services | |
ref: refs/tags/${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }} | |
path: backend | |
- name: Create Backend Deployment Package | |
working-directory: ./backend | |
run: zip -r deploy_package.zip ./ | |
- name: Upload Deployment Package to S3 | |
working-directory: ./backend | |
run: aws s3 cp deploy_package.zip s3://hydroserver-django-${{ github.event.inputs.environment }}-${{ vars.AWS_ACCOUNT_ID }}/deploy_package_${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}.zip | |
- name: Configure Environment Variables | |
working-directory: ./backend | |
run: | | |
cat << EOF > environment.json | |
[ | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "ADMIN_EMAIL", | |
"Value": "${{ vars.ADMIN_EMAIL }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "ALLOWED_HOSTS", | |
"Value": "${{ vars.ALLOWED_HOSTS }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "AWS_STORAGE_BUCKET_NAME", | |
"Value": "hydroserver-storage-${{ github.event.inputs.environment }}-${{ vars.AWS_ACCOUNT_ID }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "DATABASE_URL", | |
"Value": "${{ secrets.DATABASE_URL }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "DEBUG", | |
"Value": "${{ vars.DEBUG }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "DEPLOYMENT_BACKEND", | |
"Value": "aws" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "DISABLE_ACCOUNT_CREATION", | |
"Value": "${{ vars.DISABLE_ACCOUNT_CREATION }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "EMAIL_HOST", | |
"Value": "${{ vars.EMAIL_HOST }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "EMAIL_PORT", | |
"Value": "${{ vars.EMAIL_PORT }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "EMAIL_HOST_USER", | |
"Value": "${{ secrets.EMAIL_HOST_USER }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "EMAIL_HOST_PASSWORD", | |
"Value": "${{ secrets.EMAIL_HOST_PASSWORD }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "OAUTH_GOOGLE_CLIENT", | |
"Value": "${{ secrets.OAUTH_GOOGLE_CLIENT }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "OAUTH_GOOGLE_SECRET", | |
"Value": "${{ secrets.OAUTH_GOOGLE_SECRET }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "OAUTH_HYDROSHARE_CLIENT", | |
"Value": "${{ secrets.OAUTH_HYDROSHARE_CLIENT }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "OAUTH_HYDROSHARE_SECRET", | |
"Value": "${{ secrets.OAUTH_HYDROSHARE_SECRET }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "OAUTH_ORCID_CLIENT", | |
"Value": "${{ secrets.OAUTH_ORCID_CLIENT }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "OAUTH_ORCID_SECRET", | |
"Value": "${{ secrets.OAUTH_ORCID_SECRET }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "PROXY_BASE_URL", | |
"Value": "${{ vars.PROXY_BASE_URL }}" | |
}, | |
{ | |
"Namespace": "aws:elasticbeanstalk:application:environment", | |
"OptionName": "SECRET_KEY", | |
"Value": "${{ secrets.DJANGO_SECRET_KEY }}" | |
} | |
] | |
EOF | |
- name: Check if ElasticBeanstalk Application Version Exists | |
id: eb_version_exists | |
working-directory: ./backend | |
run: | | |
aws elasticbeanstalk describe-application-versions \ | |
--application-name hydroserver-${{ github.event.inputs.environment }} \ | |
--version-label "${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}" \ | |
|| echo "Application version does not exist." | |
- name: Delete Existing ElasticBeanstalk Application Version | |
if: success() && steps.eb_version_exists.outputs != '' # Only run if the version exists | |
working-directory: ./backend | |
run: | | |
aws elasticbeanstalk delete-application-version \ | |
--application-name hydroserver-${{ github.event.inputs.environment }} \ | |
--version-label "${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}" \ | |
--delete-source-bundle | |
- name: Create ElasticBeanstalk Application Version | |
working-directory: ./backend | |
run: | | |
aws elasticbeanstalk create-application-version \ | |
--application-name hydroserver-${{ github.event.inputs.environment }} \ | |
--source-bundle S3Bucket="hydroserver-django-${{ github.event.inputs.environment }}-${{ vars.AWS_ACCOUNT_ID }}",S3Key="deploy_package_${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}.zip" \ | |
--version-label "${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}" \ | |
--description "HydroServer Version ${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}" \ | |
--auto-create-application | |
- name: Update ElasticBeanstalk Environment | |
working-directory: ./backend | |
run: | | |
aws elasticbeanstalk update-environment \ | |
--environment-name hydroserver-${{ github.event.inputs.environment }}-env \ | |
--version-label "${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }}" \ | |
--option-settings file://environment.json | |
- name: Install Django Dependencies | |
working-directory: ./backend | |
run: | | |
python -m pip install --upgrade pip | |
pip install -r requirements.txt | |
pip install pyopenssl --upgrade | |
- name: Configure Environment Variables | |
working-directory: ./backend | |
run: | | |
cat << EOF > .env | |
PROXY_BASE_URL=http://127.0.0.1:8000 | |
DATABASE_URL=${{ secrets.DATABASE_URL }} | |
DEPLOYED=True | |
AWS_STORAGE_BUCKET_NAME=hydroserver-storage-${{ github.event.inputs.environment }}-${{ vars.AWS_ACCOUNT_ID }} | |
EOF | |
- name: Run Django Update Commands | |
working-directory: ./backend | |
env: | |
DJANGO_SETTINGS_MODULE: hydroserver.settings | |
run: | | |
python manage.py migrate | |
deploy-frontend: | |
name: Build and Deploy Frontend | |
runs-on: ubuntu-latest | |
environment: ${{ github.event.inputs.environment }} | |
steps: | |
- name: configureawscredentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_IAM_ROLE }} | |
role-session-name: create-hydroserver-resources | |
aws-region: ${{ vars.AWS_REGION }} | |
- name: Get Latest HydroServer Version | |
id: get_latest_tag | |
run: echo "tag=$(curl -sL https://api.github.com/repos/hydroserver2/hydroserver-data-management-app/releases/latest | jq -r '.tag_name')" >> $GITHUB_OUTPUT | |
- name: Checkout Frontend Repo | |
uses: actions/checkout@v4 | |
with: | |
repository: hydroserver2/hydroserver-data-management-app | |
ref: refs/tags/${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }} | |
path: frontend | |
- name: Setup Node 18.x | |
uses: actions/setup-node@v3 | |
with: | |
node-version: 18.x | |
cache: npm | |
cache-dependency-path: frontend/package-lock.json | |
- name: Install Dependencies | |
working-directory: ./frontend | |
run: npm ci | |
- name: Configure Environment Variables | |
working-directory: ./frontend | |
run: | | |
cat << EOF > .env | |
VITE_APP_VERSION=${{ github.event.inputs.hydroserver-version || steps.get_latest_tag.outputs.tag }} | |
VITE_APP_GOOGLE_MAPS_API_KEY=${{ secrets.GOOGLE_MAPS_API_KEY }} | |
VITE_APP_GOOGLE_MAPS_MAP_ID=${{ secrets.GOOGLE_MAPS_MAP_ID }} | |
VITE_APP_PROXY_BASE_URL=${{ vars.PROXY_BASE_URL }} | |
VITE_APP_DISABLE_ACCOUNT_CREATION=${{ vars.DISABLE_ACCOUNT_CREATION == 'True' && 'true' || 'false' }} | |
VITE_APP_GOOGLE_OAUTH_ENABLED=${{ secrets.OAUTH_GOOGLE_CLIENT && 'true' || 'false' }} | |
VITE_APP_ORCID_OAUTH_ENABLED=${{ secrets.OAUTH_ORCID_CLIENT && 'true' || 'false' }} | |
VITE_APP_HYDROSHARE_OAUTH_ENABLED=${{ secrets.OAUTH_HYDROSHARE_CLIENT && 'true' || 'false' }} | |
- name: Build Frontend | |
working-directory: ./frontend | |
run: npm run build | |
- name: Deploy to S3 | |
working-directory: ./frontend | |
run: | | |
aws s3 sync ./dist s3://hydroserver-web-${{ github.event.inputs.environment }}-${{ vars.AWS_ACCOUNT_ID }}/ --delete | |
- name: Invalidate CloudFront Distribution Cache | |
run: | | |
aws cloudfront create-invalidation --distribution-id ${{ vars.CLOUDFRONT_ID }} --paths "/*" |