diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ac69008 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +Dockerfile +charts/ +bin/ +obj/ diff --git a/.github/workflows/weatherhub.yml b/.github/workflows/weatherhub.yml new file mode 100644 index 0000000..e77380e --- /dev/null +++ b/.github/workflows/weatherhub.yml @@ -0,0 +1,127 @@ +# This workflow will build and push an application to a Azure Kubernetes Service (AKS) cluster when you push your code +# +# This workflow assumes you have already created the target AKS cluster and have created an Azure Container Registry (ACR) +# The ACR should be attached to the AKS cluster +# For instructions see: +# - https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough-portal +# - https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal +# - https://learn.microsoft.com/en-us/azure/aks/cluster-container-registry-integration?tabs=azure-cli#configure-acr-integration-for-existing-aks-clusters +# - https://github.com/Azure/aks-create-action +# +# To configure this workflow: +# +# 1. Set the following secrets in your repository (instructions for getting these can be found at https://docs.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-cli%2Clinux): +# - AZURE_CLIENT_ID +# - AZURE_TENANT_ID +# - AZURE_SUBSCRIPTION_ID +# +# 2. Set the following environment variables (or replace the values below): +# - ACR_RESOURCE_GROUP (resource group of your ACR) +# - AZURE_CONTAINER_REGISTRY (name of your container registry / ACR) +# - CLUSTER_RESOURCE_GROUP (where your cluster is deployed) +# - CLUSTER_NAME (name of your AKS cluster) +# - CONTAINER_NAME (name of the container image you would like to push up to your ACR) +# - DEPLOYMENT_MANIFEST_PATH (path to the manifest yaml for your deployment) +# - DOCKER_FILE (path to your Dockerfile) +# - BUILD_CONTEXT_PATH (path to the context of your Dockerfile) +# - NAMESPACE (namespace to deploy your application) +# +# For more information on GitHub Actions for Azure, refer to https://github.com/Azure/Actions +# For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples +# For more options with the actions used below please refer to https://github.com/Azure/login + +name: weatherhub + +on: + push: + branches: [aks] + workflow_dispatch: + +env: + ACR_RESOURCE_GROUP: joarteir-aks-auto + AZURE_CONTAINER_REGISTRY: arteiroacr + CONTAINER_NAME: weatherhubweb + CLUSTER_RESOURCE_GROUP: joarteir-aks-auto + CLUSTER_NAME: aks-auto + DEPLOYMENT_MANIFEST_PATH: | + manifests/deployment.yaml + manifests/service.yaml + DOCKER_FILE: Dockerfile + BUILD_CONTEXT_PATH: ./ + NAMESPACE: weatherapp + +jobs: + buildImage: + permissions: + contents: read + id-token: write + runs-on: ubuntu-latest + steps: + # Checks out the repository this file is in + - uses: actions/checkout@v3 + + # Logs in with your Azure credentials + - name: Azure login + uses: azure/login@v1.4.6 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + # Builds and pushes an image up to your Azure Container Registry + - name: Build and push image to ACR + run: | + az acr build --image ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} --registry ${{ env.AZURE_CONTAINER_REGISTRY }} -g ${{ env.ACR_RESOURCE_GROUP }} -f ${{ env.DOCKER_FILE }} ${{ env.BUILD_CONTEXT_PATH }} + deploy: + permissions: + actions: read + contents: read + id-token: write + runs-on: ubuntu-latest + needs: [buildImage] + steps: + # Checks out the repository this file is in + - uses: actions/checkout@v3 + + # Logs in with your Azure credentials + - name: Azure login + uses: azure/login@v1.4.6 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + # Use kubelogin to configure your kubeconfig for Azure auth + - name: Set up kubelogin for non-interactive login + uses: azure/use-kubelogin@v1 + with: + kubelogin-version: 'v0.0.25' + + # Retrieves your Azure Kubernetes Service cluster's kubeconfig file + - name: Get K8s context + uses: azure/aks-set-context@v3 + with: + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} + cluster-name: ${{ env.CLUSTER_NAME }} + admin: 'false' + use-kubelogin: 'true' + + # Checks if the AKS cluster is private + - name: Is private cluster + id: isPrivate + run: | + result=$(az aks show --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.CLUSTER_NAME }} --query "apiServerAccessProfile.enablePrivateCluster") + echo "PRIVATE_CLUSTER=$result" >> "$GITHUB_OUTPUT" + + # Deploys application based on given manifest file + - name: Deploys application + uses: Azure/k8s-deploy@v4 + with: + action: deploy + manifests: ${{ env.DEPLOYMENT_MANIFEST_PATH }} + images: | + ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} + resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} + name: ${{ env.CLUSTER_NAME }} + private-cluster: ${{ steps.isPrivate.outputs.PRIVATE_CLUSTER == 'true' }} + namespace: ${{ env.NAMESPACE }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a7032f3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder +WORKDIR /app + +# caches restore result by copying csproj file separately +COPY *.csproj . +RUN dotnet restore + +COPY . . +RUN dotnet publish --output /app/ --configuration Release --no-restore +RUN sed -n 's:.*\(.*\).*:\1:p' *.csproj > __assemblyname +RUN if [ ! -s __assemblyname ]; then filename=$(ls *.csproj); echo ${filename%.*} > __assemblyname; fi + +# Stage 2 +FROM mcr.microsoft.com/dotnet/aspnet:8.0 +WORKDIR /app +COPY --from=builder /app . + +ENV PORT 8080 +EXPOSE 8080 + +ENTRYPOINT dotnet $(cat /app/__assemblyname).dll --urls "http://*:8080" diff --git a/manifests/deployment.yaml b/manifests/deployment.yaml new file mode 100644 index 0000000..de4e2f2 --- /dev/null +++ b/manifests/deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: weatherhub + labels: + app: weatherhub + kubernetes.azure.com/generator: devhub + namespace: weatherapp +spec: + replicas: 1 + selector: + matchLabels: + app: weatherhub + template: + metadata: + labels: + app: weatherhub + spec: + containers: + - name: weatherhub + image: arteiroacr.azurecr.io/weatherhubweb:latest + imagePullPolicy: Always + ports: + - containerPort: 8080 diff --git a/manifests/service.yaml b/manifests/service.yaml new file mode 100644 index 0000000..269e410 --- /dev/null +++ b/manifests/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: weatherhub + namespace: weatherapp + labels: + kubernetes.azure.com/generator: devhub +spec: + type: LoadBalancer + selector: + app: weatherhub + ports: + - protocol: TCP + port: 80 + targetPort: 8080