Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: terraform app service deployment #2123

Merged
merged 4 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions docs/deployment/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ The Django application gets built into a [Docker image][dockerfile] with [NGINX]
The application is deployed to an [Azure Web App Container][az-webapp] using three separate environments for `dev`, `test`,
and `prod`.

A [GitHub Action][gh-actions] per environment is responsible for building that branch's image and pushing to [GitHub Container
Registry (GHCR)][ghcr].

GitHub POSTs a [webhook][gh-webhooks] to the Azure Web App when an [image is published to GHCR][gh-webhook-event], telling
Azure to restart the app and pull the latest image.
The [Deploy](deploy-workflow) workflow is responsible for building that branch's image and pushing to [GitHub Container
Registry (GHCR)][ghcr]. It also deploys to the Azure Web App, telling Azure to restart the app and pull the latest image.

You can view what Git commit is deployed for a given environment by visitng the URL path `/static/sha.txt`.

Expand All @@ -30,14 +27,11 @@ Docker images for each of the deploy branches are available from GitHub Containe

- [Repository Package page](https://github.com/cal-itp/benefits/pkgs/container/benefits)
- Image path: `ghcr.io/cal-itp/benefits`
- Image tags: `dev`, `test`, `prod`

[oet]: https://techblog.cdt.ca.gov/2020/06/cdt-taking-the-lead-in-digital-transformation/
[app-service-containers]: https://docs.microsoft.com/en-us/azure/app-service/configure-custom-container
[app-service]: https://docs.microsoft.com/en-us/azure/app-service/overview
[deploy-workflow]: https://github.com/cal-itp/benefits/blob/dev/.github/workflows/deploy.yml
[dockerfile]: https://github.com/cal-itp/benefits/blob/dev/Dockerfile
[az-webapp]: https://azure.microsoft.com/en-us/services/app-service/containers/
[gh-actions]: https://docs.github.com/en/actions
[gh-webhook-event]: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#package
[gh-webhooks]: https://docs.github.com/en/github-ae@latest/developers/webhooks-and-events/webhooks
[ghcr]: https://github.com/features/packages
5 changes: 2 additions & 3 deletions docs/deployment/infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,10 @@ Use the following shorthand for conveying the Resource Type as part of the Resou

## Azure environment setup

The following steps are required to set up the environment, with linked issues to automate them:
The following steps are required to set up the environment:

- `terraform apply`
- Set up Slack notifications by [creating a Slack email](https://slack.com/help/articles/206819278-Send-emails-to-Slack) for the [#benefits-notify](https://cal-itp.slack.com/archives/C022HHSEE3F) channel, then [setting it as a Secret in the Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/secrets/quick-create-portal#add-a-secret-to-key-vault) named `slack-benefits-notify-email`
- Set up Slack notifications by [creating a Slack email](https://slack.com/help/articles/206819278-Send-emails-to-Slack) for the [#notify-benefits](https://cal-itp.slack.com/archives/C022HHSEE3F) channel, then [setting it as a Secret in the Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/secrets/quick-create-portal#add-a-secret-to-key-vault) named `slack-benefits-notify-email`
- Set required [App Service configuration](../configuration/environment-variables.md) and [configuration](../configuration/data.md) by setting values in Key Vault (the mapping is defined in [app_service.tf](https://github.com/cal-itp/benefits/blob/dev/terraform/app_service.tf))
- [Set up webhook from GitHub](https://github.com/cal-itp/benefits/settings/hooks) to [App Service Deployment Center](https://learn.microsoft.com/en-us/azure/app-service/deploy-ci-cd-custom-container?tabs=acr&pivots=container-linux) for the `Packages` event

This is not a complete step-by-step guide; more a list of things to remember. This may be useful as part of [incident response](https://docs.google.com/document/d/1qtev8qItPiTB4Tp9FQ87XsLtWZ4HlNXqoe9vF2VuGcY/edit#).
5 changes: 2 additions & 3 deletions docs/deployment/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,15 @@ Using the `github.actor` and built-in `GITHUB_TOKEN` secret

### 3. Build and push image to GitHub Container Registry (GHCR)

Build the root [`Dockerfile`][dockerfile], tagging with both the branch name (e.g. `dev`) and the SHA from the HEAD commit.
Build the root [`Dockerfile`][dockerfile], tagging with the SHA from the HEAD commit.

Push this image:tag into [GHCR][ghcr].

### 4. App Service deploy

Each Azure App Service instance is configured to [listen to a webhook from GitHub, then deploy the image][webhook].
Push the new image:tag to the Azure App Service instance.

[deploy]: https://github.com/cal-itp/benefits/blob/dev/.github/workflows/deploy.yml
[dockerfile]: https://github.com/cal-itp/benefits/blob/dev/Dockerfile
[ghcr]: https://github.com/features/packages
[gh-actions-trigger]: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
[webhook]: https://docs.microsoft.com/en-us/azure/app-service/deploy-ci-cd-custom-container
23 changes: 17 additions & 6 deletions terraform/app_service.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ resource "azurerm_linux_web_app" "main" {
site_config {
ftps_state = "Disabled"
vnet_route_all_enabled = true
application_stack {
docker_image = "ghcr.io/cal-itp/benefits"
docker_image_tag = local.env_name
}
}

identity {
Expand All @@ -52,8 +48,7 @@ resource "azurerm_linux_web_app" "main" {
# app setting used solely for refreshing secrets - see https://github.com/MicrosoftDocs/azure-docs/issues/79855#issuecomment-1265664801
"change_me_to_refresh_secrets" = "change me in the portal to refresh all secrets",

"DOCKER_ENABLE_CI" = "true",
"DOCKER_REGISTRY_SERVER_URL" = "https://ghcr.io/",
"DOCKER_ENABLE_CI" = "false",
"WEBSITE_HTTPLOGGING_RETENTION_DAYS" = "99999",
"WEBSITE_TIME_ZONE" = "America/Los_Angeles",
"WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false",
Expand Down Expand Up @@ -110,6 +105,22 @@ resource "azurerm_linux_web_app" "main" {
}
}

resource "azurerm_app_service_source_control" "main" {
app_id = azurerm_linux_web_app.main.id
repo_url = "https://github.com/cal-itp/benefits"
branch = local.env_name
rollback_enabled = true

github_action_configuration {
generate_workflow_file = false

container_configuration {
image_name = "cal-itp/benefits"
registry_url = "https://ghcr.io/"
}
}
}

resource "azurerm_app_service_custom_hostname_binding" "main" {
hostname = local.hostname
app_service_name = azurerm_linux_web_app.main.name
Expand Down
Loading