-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create automated deployment to Azure Container app (#39)
* Refactor environment vars: - Github secrets for buildArguments - Github repository variables for non-secrets - Azure Container app secrets for secrets * Diagrams for system architecture * Architecture design decisions
- Loading branch information
Showing
17 changed files
with
394 additions
and
9 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
...ub/workflows/prod-slack-altinn-AutoDeployTrigger-06da9e65-21d6-4cd0-803b-5776683d6cfc.yml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
name: prod-slack-altinn - Auto deploy | ||
|
||
# When this action will be executed | ||
on: | ||
# Automatically trigger it when detected changes in repo | ||
push: | ||
branches: | ||
[ release ] | ||
paths: | ||
- '**' | ||
- '.github/workflows/prod-slack-altinn-AutoDeployTrigger-06da9e65-21d6-4cd0-803b-5776683d6cfc.yml' | ||
|
||
# Allow manual trigger | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build-and-deploy: | ||
runs-on: ubuntu-latest | ||
environment: prod-slack-altinn | ||
|
||
steps: | ||
- name: Checkout to the branch | ||
uses: actions/checkout@v4 | ||
|
||
- name: Azure Login | ||
uses: azure/login@v2 | ||
with: | ||
creds: ${{ secrets.DIGDIRASSISTANTSALTINN_AZURE_CREDENTIALS }} | ||
|
||
- name: Build and push container image to registry | ||
uses: azure/container-apps-deploy-action@v2 | ||
with: | ||
appSourcePath: ${{ github.workspace }} | ||
registryUrl: altinnaicontainers.azurecr.io | ||
registryUsername: ${{ secrets.DIGDIRASSISTANTSALTINN_REGISTRY_USERNAME }} | ||
registryPassword: ${{ secrets.DIGDIRASSISTANTSALTINN_REGISTRY_PASSWORD }} | ||
containerAppName: digdir-assistants-altinn | ||
resourceGroup: altinn-ai-assistant | ||
imageToBuild: altinnaicontainers.azurecr.io/digdir-assistants-prod:${{ github.sha }} | ||
environmentVariables: VITE_SLACK_APP_SUPABASE_API_URL=${{secrets.VITE_SLACK_APP_SUPABASE_API_URL}} VITE_SLACK_APP_SUPABASE_ANON_KEY=${{secrets.VITE_SLACK_APP_SUPABASE_ANON_KEY}} | ||
|
||
|
||
|
||
|
||
|
45 changes: 45 additions & 0 deletions
45
...kflows/prod-slack-altinndevops-AutoDeployTrigger-bbf1dda7-6862-4a86-94e1-9466cec169a6.yml
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
name: prod-slack-altinndevops - Auto deploy | ||
|
||
# When this action will be executed | ||
on: | ||
# Automatically trigger it when detected changes in repo | ||
push: | ||
branches: | ||
[ release ] | ||
paths: | ||
- '**' | ||
- '.github/workflows/prod-slack-altinndevops-AutoDeployTrigger-bbf1dda7-6862-4a86-94e1-9466cec169a6.yml' | ||
|
||
# Allow manual trigger | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build-and-deploy: | ||
runs-on: ubuntu-latest | ||
environment: prod-slack-altinndevops | ||
|
||
steps: | ||
- name: Checkout to the branch | ||
uses: actions/checkout@v4 | ||
|
||
- name: Azure Login | ||
uses: azure/login@v2 | ||
with: | ||
creds: ${{ secrets.DIGDIRASSISTANTS_AZURE_CREDENTIALS }} | ||
|
||
- name: Build and push container image to registry | ||
uses: azure/container-apps-deploy-action@v2 | ||
with: | ||
appSourcePath: ${{ github.workspace }} | ||
registryUrl: altinnaicontainers.azurecr.io | ||
registryUsername: ${{ secrets.DIGDIRASSISTANTS_REGISTRY_USERNAME }} | ||
registryPassword: ${{ secrets.DIGDIRASSISTANTS_REGISTRY_PASSWORD }} | ||
containerAppName: digdir-assistants | ||
resourceGroup: altinn-ai-assistant | ||
imageToBuild: altinnaicontainers.azurecr.io/digdir-assistants-prod:${{ github.sha }} | ||
environmentVariables: VITE_SLACK_APP_SUPABASE_API_URL=${{secrets.VITE_SLACK_APP_SUPABASE_API_URL}} VITE_SLACK_APP_SUPABASE_ANON_KEY=${{secrets.VITE_SLACK_APP_SUPABASE_ANON_KEY}} | ||
|
||
|
||
|
||
|
||
|
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Architecture and design decisions | ||
|
||
## Database as a service | ||
|
||
When considering alternatives for storing stateful and static data for Altinn Assistant, we prioritized the following desirable characteristics: | ||
|
||
1. **Real-time Data Synchronization**: Supabase provides real-time change data notification and synchronization capabilities and offers client implementations for multiple langauages, including TypeScript. | ||
2. **Security**: Supabase provides enterprise-grade security features, including encryption at rest and in transit, fine-grained access control, and built-in auditing and logging. | ||
3. **Integration with Other Services**: Supabase provides native integration with other services, such as Supabase Auth, Supabase Realtime, and Supabase Storage, making it easy to build comprehensive applications. | ||
4. **Open-Source**: Supabase is open-source, which means that it is free, and the source code is publicly available for anyone to inspect, modify, and contribute to. | ||
5. **Self-host and cloud hosting options**: Supabase provides a secure cloud hosting environment for database storage and query execution. Additionally, Supabase Functions can be hosted within a secure cloud subnetwork without the administrative overhead normally required. | ||
6. **Web-based Interface**: Supabase provides a simplified web-based interface for managing databases, users, and permissions, making it easy to set up and manage databases. This interface was especially relevant during the early stages of prototyping and postponed the urgency of developing a custom admin interface. | ||
7. **SQL and NoSQL Support**: Supabase supports both SQL and NoSQL data models, allowing developers to choose the best approach for their application's specific needs. | ||
8. **Performance**: Supabase uses a highly optimized PostgreSQL engine, which is renowned for its performance and reliability. Supabase also provides multiple geographic locations for data storage, ensuring lower latency and faster query times. | ||
9. **Language agnostic**: Supabase Functions support multiple programming languages, making it accessible to a wide range of developers. | ||
10. **Scalability**: Supabase is designed to scale horizontally, allowing it to handle large volumes of data and high traffic, making it suitable for high-traffic applications. | ||
11. **High Availability**: Supabase uses a distributed architecture, ensuring that data is replicated across multiple nodes, ensuring high availability even in the event of node failures or network outages. | ||
12. **PostgreSQL Compatibility**: Supabase is fully compatible with PostgreSQL, allowing developers to leverage their existing knowledge and skills. | ||
13. **API-based**: Supabase provides a robust API for interacting with the database, making it easy to integrate with other applications and services. | ||
14. **Automated Backup and Recovery**: Supabase provides automated backup and recovery features, ensuring that data is safely backed up and can be quickly restored in the event of a disaster. | ||
|
||
|
||
|
||
## Functions as a service | ||
|
||
One of the key benefits of using Supabase DB is that most data operations for our application can be achieved without any backend code. Through properly designed access control policies, we can retrieve relevant data directly from the front end application running in the browser. Especially during the early stages of prototyping, this can be a significant time saver. | ||
|
||
Should the need arise for complicated data manipulation or querying, we can add a serverless backend function for that specific purpose, without a costly rearchitecture effort. Additionally, each function can have it's own scaling configuration, source code language and security context. While not suitable for all workloads, Supabase Functions have the general benefits associated with serverless runtimes in general: | ||
|
||
* **Cost savings**: Pay only for the resources consumed, which can lead to significant cost savings. | ||
* **Increased scalability**: Infrastructure scaling is automated, ensuring your application can handle changing traffic patterns. | ||
* **Reduced administrative burden**: No need to manage servers, patch software, or worry about security updates. | ||
* **Faster deployment**: Developers can focus on writing code, rather than managing infrastructure. | ||
* **Improved responsiveness**: Functions can respond quickly to changing traffic patterns, ensuring a better user experience. | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
|
||
# Create a Container App - step by step | ||
|
||
### Step 1 | ||
|
||
- Select your new resource group and Container Apps Environment | ||
|
||
![Create a Container app - step 1](/documentation/azure/new-container-app_step-1.png) | ||
|
||
--- | ||
|
||
|
||
### Step 2 | ||
|
||
- Be sure to select the correct repository and image name. | ||
- The image tag is not important, as we will specific a dynamic git commit in the deployment workflow. | ||
|
||
![Create a Container app - step 2](/documentation/azure/new-container-app_step-2.jpg) | ||
|
||
--- | ||
|
||
### Step 3 | ||
|
||
Recommended settings: | ||
- Ingress should be enabled and ***Accepting traffic from anywhere*** | ||
- Ingress type: HTTP | ||
- Client certificate mode: Ignore | ||
- Transport: Auto | ||
- Insecure connections: false | ||
- Target port: 3000 | ||
- Session affinity: false | ||
|
||
![Create a Container app - step 3](/documentation/azure/new-container-app_step-3.jpg) | ||
|
||
|
||
|
||
### Step 4 | ||
|
||
Configure continuous integration: | ||
- Sign-in with your Github credentials, allowing Azure to access the repository and store required secrets | ||
- Select the correct Organization, Repository and Branch to match your own fork. | ||
- Configure Registry settings to match your new Docker image repository. | ||
- Azure access: | ||
- Important: as of this writing, User-assigned identity does NOT work with Github Action secrets. Instead, select Service Principal. | ||
- Click "Start continuous deployment" | ||
- This will generate and commit a new Github Action workflow file in the `.github` folder of your code repository. | ||
- Unfortunately, the template used is out of date and needs to be manually updated in a separate commit. We'll fix this in the last step. | ||
|
||
|
||
![Setup CI](/documentation/azure/setup-ci_step-1.png) | ||
|
||
|
||
|
||
### Step 5 - Add environment to Github actions config | ||
|
||
- Under "Environments", add a suitable environment name, ex. "prod-slack-<your-slack-workspace-name>" | ||
|
||
![Setup environments in Github](/documentation/github/setup-environments.jpg) | ||
|
||
|
||
### Step 6 - configure Supabase variables | ||
|
||
In your Supabase project settings area, under "API", locate your ANON KEY and project url. You will use these values in the next step. | ||
|
||
![Supabase project settings](/documentation/supabase/locate-project-settings.jpg) | ||
|
||
|
||
### Step 7 - Set environment secrets | ||
|
||
Under "Secrets and variables" > "Actions", add the following variables for *each* environment: | ||
- SLACK_APP_SUPABASE_ANON_KEY | ||
|
||
|
||
You will note that there are some existing secrets under "Repository secrets", created for you by the Azure Container App CI setup wizard. You shouldn't need to modify these, except to cleanup any removed Container Apps. | ||
|
||
![Setup environment secrets](/documentation/github/environment-secrets.jpg) | ||
|
||
|
||
### Step 8 - Set repository variables | ||
|
||
Still under "Secrets and variables", click "Variables". | ||
|
||
Add the listed repository variables first, adjusting the values as desired. These values serve as a useful default for all environments, reducing the number of environment variables to maintain. | ||
|
||
|
||
|
||
![Setup repository variables](/documentation/github/set-repository-variables.jpg) | ||
|
||
|
||
### Step 9 - Set Environment variables | ||
|
||
Finally, add environment specific variable values for each repository variable you want to override the default value of. Typical examples include: | ||
- SLACK_APP_SUPABASE_API_URL | ||
- TYPESENSE_DOCS_COLLECTION | ||
- TYPESENSE_DOCS_SEARCH_PHRASE_COLLECTION | ||
|
||
|
||
### Step 10 - Set container secrets | ||
|
||
Add the following secrets to the container app using the Azure portal: | ||
|
||
![Setup Azure container app secrets](/documentation/azure/create-secrets.jpg) | ||
|
||
|
||
You will find your Slack secrets in the Slack app configuration UI. | ||
|
||
### Step 11 - Fix deployment workflow | ||
|
||
See workflows in the `.github` folder for working examples. | ||
|
||
Adjust the generated workflow file to be similar to one of the working examples, substituting the correct environment name where applicable. | ||
|
||
Confirm that Github action for build-and-deploy is successful. | ||
|
||
### Step 12 - Change scaling and activation config | ||
|
||
By default, your Container app will scale to zero instances. For environments with sporadic usage, this can be acceptable. However, for most test and production environments, this will cause an unacceptable delay for Slack users. | ||
|
||
We recommend changing the scale configuration to a minimum of 1 instance, to avoid latency due to cold start. | ||
|
||
For development and test environments, we recommend Revision mode: Single. | ||
|
||
For production environments, we recommend Revision mode: Multiple, as it makes it much easier to rollback to a known good container instance, should there be problems with a deploy. |
Oops, something went wrong.