Skip to content

Commit

Permalink
Containerise api + website (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
benchiverton authored Jun 25, 2024
1 parent a28b13b commit 8239ec0
Show file tree
Hide file tree
Showing 22 changed files with 290 additions and 219 deletions.
19 changes: 0 additions & 19 deletions .github/workflows/build-all.yml

This file was deleted.

71 changes: 37 additions & 34 deletions .github/workflows/instance-deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@ jobs:
with:
solution_file: "src/Api/Company.Api.sln"
project_file: "src/Api/Company.Api/Company.Api.csproj"
dotnet_version: 7.0.302
artifact_name: "api"
self_contained: false
dotnet_version: 8.0.203
dockerfile_name: "src/Api/Company.Api/dockerfile"
image_name: "onlinestore-api"
secrets: inherit

build-website:
uses: benchiverton/OnlineStore/.github/workflows/workflow-build-test-publish-dotnet.yml@main
with:
solution_file: "src/Website/Company.Website.sln"
project_file: "src/Website/Company.Website/Company.Website.csproj"
dotnet_version: 7.0.302
artifact_name: "website"
self_contained: true
dotnet_version: 8.0.203
dockerfile_name: "src/Website/Company.Website/dockerfile"
image_name: "onlinestore-website"
secrets: inherit

deploy-terraform-prod:
needs: [variables, build-api, build-website]
Expand Down Expand Up @@ -95,10 +97,10 @@ jobs:
- name: Save terraform outputs
shell: bash
run: |
terraform -chdir=instance output -raw web_app_api_name > web_app_api_name.txt
terraform -chdir=instance output -raw web_app_api_hostname > web_app_api_hostname.txt
terraform -chdir=instance output -raw web_app_website_name > web_app_website_name.txt
terraform -chdir=instance output -raw web_app_website_hostname > web_app_website_hostname.txt
terraform -chdir=instance output -raw resource_group_name > terraform-outputs/resource_group_name.txt
terraform -chdir=instance output -raw container_app_api_fqdn > terraform-outputs/container_app_api_fqdn.txt
terraform -chdir=instance output -raw container_app_website_fqdn > terraform-outputs/container_app_website_fqdn.txt
terraform -chdir=instance output -raw container_instance_monitoring_fqdn > terraform-outputs/container_instance_monitoring_fqdn.txt
# -raw cannot handle null values - https://github.com/hashicorp/terraform/issues/32384
terraform -chdir=instance show -json | jq -r '.values.outputs.container_instance_monitoring_fqdn.value // ""' > container_instance_monitoring_fqdn.txt
- name: Upload terraform outputs for deploy job
Expand All @@ -122,34 +124,35 @@ jobs:
id: vars
shell: bash
run: |
echo "web_app_api_name=$(cat web_app_api_name.txt)" >> $GITHUB_ENV
echo "web_app_api_hostname=$(cat web_app_api_hostname.txt)" >> $GITHUB_ENV
echo "web_app_website_name=$(cat web_app_website_name.txt)" >> $GITHUB_ENV
echo "web_app_website_hostname=$(cat web_app_website_hostname.txt)" >> $GITHUB_ENV
echo "resource_group_name=$(cat resource_group_name.txt)" >> $GITHUB_ENV
echo "container_app_api_fqdn=$(cat container_app_api_fqdn.txt)" >> $GITHUB_ENV
echo "container_app_website_fqdn=$(cat container_app_website_fqdn.txt)" >> $GITHUB_ENV
echo "container_instance_monitoring_fqdn=$(cat container_instance_monitoring_fqdn.txt)" >> $GITHUB_ENV
- name: Download API package
uses: actions/download-artifact@v3
with:
name: api
path: ${{ github.workspace }}/api
- name: Download website package
uses: actions/download-artifact@v3
with:
name: website
path: ${{ github.workspace }}/website
- name: Update website config
run: echo "`jq '.Api.BasePath="https://${{ env.web_app_api_hostname }}"' ${{ github.workspace }}/website/wwwroot/appsettings.json`" > ${{ github.workspace }}/website/wwwroot/appsettings.json
- name: Login via Azure CLI
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Run Azure webapp deploy for API
uses: azure/webapps-deploy@v2
- name: Deploy api
uses: azure/container-apps-deploy-action@v1
with:
app-name: ${{ env.web_app_api_name }}
package: ${{ github.workspace }}/api
- name: Run Azure webapp deploy for website
uses: azure/webapps-deploy@v2
acrName: onlinestorecontainerregistry
acrUsername: ${{ secrets.ACR_USERNAME }}
acrPassword: ${{ secrets.ACR_TOKEN }}
containerAppName: onlinestore-api
imageToDeploy: onlinestorecontainerregistry.azurecr.io/onlinestore-api:${{ github.sha }}
location: 'East US'
resourceGroup: ${{ env.resource_group_name }}
targetPort: 8080
environmentVariables: "OTLPEXPORTER__ENDPOINT=http://${{ env.container_instance_monitoring_fqdn }}:4317"
- name: Deploy website
uses: azure/container-apps-deploy-action@v1
with:
app-name: ${{ env.web_app_website_name }}
package: ${{ github.workspace }}/website
acrName: onlinestorecontainerregistry
acrUsername: ${{ secrets.ACR_USERNAME }}
acrPassword: ${{ secrets.ACR_TOKEN }}
containerAppName: onlinestore-website
imageToDeploy: onlinestorecontainerregistry.azurecr.io/onlinestore-website:${{ github.sha }}
location: 'East US'
resourceGroup: ${{ env.resource_group_name }}
targetPort: 80
environmentVariables: "API__BASEPATH=https://${{ env.container_app_api_fqdn }}"
81 changes: 41 additions & 40 deletions .github/workflows/instance-deploy-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@ on:

jobs:
build-api:
uses: benchiverton/OnlineStore/.github/workflows/workflow-build-test-publish-dotnet.yml@main
uses: benchiverton/OnlineStore/.github/workflows/workflow-build-test-publish-dotnet.yml@containerise-apps
with:
solution_file: "src/Api/Company.Api.sln"
project_file: "src/Api/Company.Api/Company.Api.csproj"
dotnet_version: 7.0.302
artifact_name: "api"
self_contained: false
dotnet_version: 8.0.203
dockerfile_name: "src/Api/Company.Api/dockerfile"
image_name: "onlinestore-api"
secrets: inherit

build-website:
uses: benchiverton/OnlineStore/.github/workflows/workflow-build-test-publish-dotnet.yml@main
uses: benchiverton/OnlineStore/.github/workflows/workflow-build-test-publish-dotnet.yml@containerise-apps
with:
solution_file: "src/Website/Company.Website.sln"
project_file: "src/Website/Company.Website/Company.Website.csproj"
dotnet_version: 7.0.302
artifact_name: "website"
self_contained: true
dotnet_version: 8.0.203
dockerfile_name: "src/Website/Company.Website/dockerfile"
image_name: "onlinestore-website"
secrets: inherit

deploy-terraform-test:
needs: [build-api, build-website]
Expand Down Expand Up @@ -72,10 +74,10 @@ jobs:
shell: bash
run: |
mkdir terraform-outputs
terraform -chdir=instance output -raw web_app_api_name > terraform-outputs/web_app_api_name.txt
terraform -chdir=instance output -raw web_app_api_hostname > terraform-outputs/web_app_api_hostname.txt
terraform -chdir=instance output -raw web_app_website_name > terraform-outputs/web_app_website_name.txt
terraform -chdir=instance output -raw web_app_website_hostname > terraform-outputs/web_app_website_hostname.txt
terraform -chdir=instance output -raw resource_group_name > terraform-outputs/resource_group_name.txt
terraform -chdir=instance output -raw container_app_api_fqdn > terraform-outputs/container_app_api_fqdn.txt
terraform -chdir=instance output -raw container_app_website_fqdn > terraform-outputs/container_app_website_fqdn.txt
terraform -chdir=instance output -raw container_instance_monitoring_fqdn > terraform-outputs/container_instance_monitoring_fqdn.txt
# -raw cannot handle null values - https://github.com/hashicorp/terraform/issues/32384
terraform -chdir=instance show -json | jq -r '.values.outputs.container_instance_monitoring_fqdn.value // ""' > container_instance_monitoring_fqdn.txt
- name: Upload terraform outputs for deploy job
Expand All @@ -99,39 +101,38 @@ jobs:
id: vars
shell: bash
run: |
echo "web_app_api_name=$(cat web_app_api_name.txt)" >> $GITHUB_ENV
echo "web_app_api_hostname=$(cat web_app_api_hostname.txt)" >> $GITHUB_ENV
echo "web_app_website_name=$(cat web_app_website_name.txt)" >> $GITHUB_ENV
echo "web_app_website_hostname=$(cat web_app_website_hostname.txt)" >> $GITHUB_ENV
echo "resource_group_name=$(cat resource_group_name.txt)" >> $GITHUB_ENV
echo "container_app_api_fqdn=$(cat container_app_api_fqdn.txt)" >> $GITHUB_ENV
echo "container_app_website_fqdn=$(cat container_app_website_fqdn.txt)" >> $GITHUB_ENV
echo "container_instance_monitoring_fqdn=$(cat container_instance_monitoring_fqdn.txt)" >> $GITHUB_ENV
- name: Download API package
uses: actions/download-artifact@v3
with:
name: api
path: ${{ github.workspace }}/api
- name: Download website package
uses: actions/download-artifact@v3
with:
name: website
path: ${{ github.workspace }}/website
- name: Update website config
run: echo "`jq '.Api.BasePath="https://${{ env.web_app_api_hostname }}"' ${{ github.workspace }}/website/wwwroot/appsettings.json`" > ${{ github.workspace }}/website/wwwroot/appsettings.json
- name: Login via Azure CLI
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Run Azure webapp deploy for API
uses: azure/webapps-deploy@v2
id: apideploy
- name: Deploy api
uses: azure/container-apps-deploy-action@v1
with:
app-name: ${{ env.web_app_api_name }}
package: ${{ github.workspace }}/api
- name: Run Azure webapp deploy for website
uses: azure/webapps-deploy@v2
id: websitedeploy
acrName: onlinestorecontainerregistry
acrUsername: ${{ secrets.ACR_USERNAME }}
acrPassword: ${{ secrets.ACR_TOKEN }}
containerAppName: onlinestore-api
imageToDeploy: onlinestorecontainerregistry.azurecr.io/onlinestore-api:${{ github.sha }}
location: 'East US'
resourceGroup: ${{ env.resource_group_name }}
targetPort: 8080
environmentVariables: "OTLPEXPORTER__ENDPOINT=http://${{ env.container_instance_monitoring_fqdn }}:4317"
- name: Deploy website
uses: azure/container-apps-deploy-action@v1
with:
app-name: ${{ env.web_app_website_name }}
package: ${{ github.workspace }}/website
acrName: onlinestorecontainerregistry
acrUsername: ${{ secrets.ACR_USERNAME }}
acrPassword: ${{ secrets.ACR_TOKEN }}
containerAppName: onlinestore-website
imageToDeploy: onlinestorecontainerregistry.azurecr.io/onlinestore-website:${{ github.sha }}
location: 'East US'
resourceGroup: ${{ env.resource_group_name }}
targetPort: 80
environmentVariables: "API__BASEPATH=https://${{ env.container_app_api_fqdn }}"
- name: Post test environment information on PR
uses: actions/[email protected]
if: github.event_name == 'pull_request'
Expand All @@ -141,8 +142,8 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const output = `### Test environment information
#### 🔗[Visit website](https://${{ env.web_app_website_hostname }}/)
#### 🔗[Visit API](https://${{ env.web_app_api_hostname }}/swagger/)
#### 🔗[Visit website](https://${{ env.container_app_website_fqdn }}/)
#### 🔗[Visit API](https://${{ env.container_app_api_fqdn }}/swagger/)
#### 🔗[Visit monitoring UI](http://${{ env.container_instance_monitoring_fqdn }}:16686)
*Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Working Directory: \`${{ env.tf_actions_working_dir }}\`, Workflow: \`${{ github.workflow }}\`*`;
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/permanent-image-import.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ jobs:
- name: Login to ACR
uses: docker/login-action@v2
with:
registry: ${{ github.event.inputs.target_acr }}
registry: ${{ inputs.target_acr }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_TOKEN }}
- name: Pull image
run: |
docker pull docker.io/${{ github.event.inputs.image }}
docker pull docker.io/${{ inputs.image }}
- name: Re-tag image
run: |
docker tag docker.io/${{ github.event.inputs.image }} ${{ github.event.inputs.target_acr }}/${{ github.event.inputs.image }}
docker tag docker.io/${{ inputs.image }} ${{ inputs.target_acr }}/${{ inputs.image }}
- name: Publish image
run: |
docker push ${{ github.event.inputs.target_acr }}/${{ github.event.inputs.image }}
docker push ${{ inputs.target_acr }}/${{ inputs.image }}
21 changes: 20 additions & 1 deletion .github/workflows/workflow-build-test-publish-dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ on:
type: string
self_contained:
type: boolean
default: true
artifact_name:
type: string
dockerfile_name:
type: string
default: .
image_name:
type: string
target_acr:
type: string
default: onlinestorecontainerregistry.azurecr.io

jobs:
build-test:
Expand All @@ -32,7 +41,7 @@ jobs:
run: dotnet build ${{ inputs.solution_file }} --configuration Release --no-restore
- name: Test
run: dotnet test ${{ inputs.solution_file }} --configuration Release --no-build --verbosity normal
- name: Publish
- name: Publish binaries
if: ${{ inputs.artifact_name != null }}
run: dotnet publish ${{ inputs.project_file }} --configuration Release --no-build --output publish/${{ inputs.artifact_name }} --self-contained ${{ inputs.self_contained }}
- name: Publish artifact
Expand All @@ -41,3 +50,13 @@ jobs:
with:
name: ${{ inputs.artifact_name }}
path: publish/${{ inputs.artifact_name }}
- name: Build and push image
if: ${{ inputs.image_name != null }}
uses: docker/login-action@v2
with:
registry: ${{ inputs.target_acr }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_TOKEN }}
- run: |
docker image build --file ${{ inputs.dockerfile_name }} --tag ${{ inputs.target_acr }}/${{ inputs.image_name }}:${{ github.sha }} .
docker push ${{ inputs.target_acr }}/${{ inputs.image_name }}:${{ github.sha }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ bld/

# Visual Studio 2015/2017 cache/options directory
.vs/

# Rider directiry
.idea/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ The GitHub runner needs to connect to Azure Storage (Terraform state file) and o
2. (powershell) Get your subscription id (`az account list`).
3. (powershell) Specify which subscription you want to use (`az account set --subscription="SUBSCRIPTION_ID"`).
4. (powershell) Create the service principal in the 'Online Store' subscription (`az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/SUBSCRIPTION_ID" --sdk-auth`). This will output some JSON that the runner will use to log into Azure (stored in repo secret `AZURE_CREDENTIALS`). In addition, the following repository secrets should be extracted from this JSON (which are needed for terraform steps):
* *appId* - `TF_VAR_AGENT_CLIENT_ID`
* *password* - `TF_VAR_AGENT_CLIENT_SECRET`
* *tenant* - `TF_VAR_TENANT_ID`
* *subscriptionId*
* *clientId* - `TF_VAR_AGENT_CLIENT_ID`
* *clientSecret* - `TF_VAR_AGENT_CLIENT_SECRET`
* *tenantId* - `TF_VAR_TENANT_ID`

For more information, read ['Azure Provider: Authenticating using a Service Principal with a Client Secret'](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret).

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
14 changes: 7 additions & 7 deletions src/Api/Company.Api.Tests/Company.Api.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="xunit" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="coverlet.collector" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Loading

0 comments on commit 8239ec0

Please sign in to comment.