diff --git a/.github/workflows/production-pipeline.yml b/.github/workflows/production-pipeline.yml new file mode 100644 index 0000000..918c374 --- /dev/null +++ b/.github/workflows/production-pipeline.yml @@ -0,0 +1,47 @@ +name: Production pipeline + +on: + workflow_dispatch: # Allows manual execution + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@main + + - name: 'Login via Azure CLI' + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: 'Set up Kubernetes' + uses: azure/aks-set-context@v2 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + cluster-name: ${{ secrets.AKS_CLUSTER_NAME }} + resource-group: ${{ secrets.AKS_RESOURCE_GROUP }} + + - name: 'Build and push image' + uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + - run: | + docker build -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi:${{ github.sha }} -f ./docker/Dockerfile . + docker tag ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi:${{ github.sha }} ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi:latest + + docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi:${{ github.sha }} + docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi:latest + - name: 'Copy production values files' + run: | + cp ./helm-chart/values-production.yaml ./helm-chart/values.yaml + + - name: 'Deploy to AKS with Helm' + run: | + helm upgrade --install whatnow ./helm-chart \ + --namespace ${{ secrets.AKS_CLUSTER_NAMESPACE }} \ + --create-namespace + + diff --git a/.github/workflows/qa-pipeline.yml b/.github/workflows/qa-pipeline.yml new file mode 100644 index 0000000..785d809 --- /dev/null +++ b/.github/workflows/qa-pipeline.yml @@ -0,0 +1,53 @@ +name: Stage pipeline + +on: + pull_request: + types: + - closed + branches: + - 'staging' + + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@main + + - name: 'Login via Azure CLI' + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: 'Set up Kubernetes' + uses: azure/aks-set-context@v2 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + cluster-name: ${{ secrets.AKS_CLUSTER_NAME }} + resource-group: ${{ secrets.AKS_RESOURCE_GROUP }} + + - name: 'Build and push image' + uses: azure/docker-login@v1 + with: + login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + - run: | + docker build -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi-qa:${{ github.sha }} -f ./docker/Dockerfile . + docker tag ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi-qa:${{ github.sha }} ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi-qa:latest + + docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi-qa:${{ github.sha }} + docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/whatnowapi-qa:latest + + - name: 'Copy staging values file' + run: | + cp ./helm-chart/values-staging.yaml ./helm-chart/values.yaml + + - name: 'Deploy to AKS with Helm' + run: | + helm upgrade --install whatnow-qa ./helm-chart \ + --namespace ${{ secrets.AKS_CLUSTER_NAMESPACE_QA }} \ + --create-namespace + + diff --git a/.gitignore b/.gitignore index 06bc057..d3b6cf6 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,12 @@ Homestead.yaml npm-debug.log yarn-error.log helm-chart/secrets.yml -.idea/* \ No newline at end of file +.idea/* +helm-chart/fullchain.pem +helm-chart/privkey.pem +helm-chart/secrets.yml +helm-chart/secrets-ifrc.yml +helm-chart/secrets-qa.yml +helm-chart/secrets-prod.yml +helm-chart/ssl-secret.yaml +.DS_Store diff --git a/helm-chart/values-production.yaml b/helm-chart/values-production.yaml new file mode 100644 index 0000000..ad5b3fd --- /dev/null +++ b/helm-chart/values-production.yaml @@ -0,0 +1,84 @@ +# Azure Container Registry details +image: + repository: ifrcsmdb.azurecr.io/whatnowapi + tag: "latest" + pullPolicy: Always + +replicaCount: 1 + +# Kubernetes service configuration +service: + type: ClusterIP + port: 80 + targetPort: 80 +# Environment variables +env: + APP_NAME: 'IFRC National Society Preparedness Messages' + APP_ENV: production + APP_DEBUG: false + APP_LOG_LEVEL: info + APP_URL: https://api-preparemessages.ifrc.org + LOG_CHANNEL: stack + DB_PORT: 3306 + DB_CONNECTION: mysql + BROADCAST_DRIVER: log + CACHE_DRIVER: file + QUEUE_CONNECTION: sync + SESSION_DRIVER: file + SESSION_LIFETIME: 120 + REDIS_HOST: 127.0.0.1 + REDIS_PASSWORD: null + REDIS_PORT: 6379 + MAIL_DRIVER: smtp + MAIL_HOST: smtp.mailtrap.io + MAIL_PORT: 2525 + MAIL_USERNAME: null + MAIL_PASSWORD: null + MAIL_ENCRYPTION: null + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_DEFAULT_REGION: us-east-1 + AWS_BUCKET: + PUSHER_APP_ID: + PUSHER_APP_KEY: + PUSHER_APP_SECRET: + PUSHER_APP_CLUSTER: mt1 + MIX_PUSHER_APP_KEY: "${PUSHER_APP_KEY}" + MIX_PUSHER_APP_CLUSTER: "${PUSHER_APP_CLUSTER}" + AZURE_STORAGE_ACCOUNT: smdbstorageaccount + AZURE_STORAGE_CONTAINER: images + AZURE_STORAGE_DOMAIN: blob.core.windows.net + +secrets: + dbSecretName: admin-credentials + variables: + ADMIN_USER: ADMIN_USER + ADMIN_PASSWORD: ADMIN_PASSWORD + DB_HOST: DB_HOST + DB_DATABASE: DB_DATABASE + DB_USERNAME: DB_USERNAME + DB_PASSWORD: DB_PASSWORD + APP_KEY: APP_KEY + AZURE_STORAGE_KEY: AZURE_STORAGE_KEY + AZURE_STORAGE_CONNECTION_STRING: AZURE_STORAGE_CONNECTION_STRING + +# Ingress (if using) +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + hosts: + - host: "api.whatnow" + paths: + - path: / + pathType: ImplementationSpecific + - host: "api-preparemessages.ifrc.org" + paths: + - path: / + pathType: Prefix + tls: + - hosts: + - "api-preparemessages.ifrc.org" + secretName: "ifrc.certificates.secret" diff --git a/helm-chart/values-staging.yaml b/helm-chart/values-staging.yaml new file mode 100644 index 0000000..d397c89 --- /dev/null +++ b/helm-chart/values-staging.yaml @@ -0,0 +1,83 @@ +# Azure Container Registry details +image: + repository: ifrcsmdb.azurecr.io/whatnowapi-qa + tag: "latest" + pullPolicy: Always + +replicaCount: 1 + +# Kubernetes service configuration +service: + type: ClusterIP + port: 80 + targetPort: 80 +# Environment variables +env: + APP_NAME: Laravel + APP_ENV: stage + APP_DEBUG: false + APP_URL: http://localhost + LOG_CHANNEL: stack + DB_PORT: 3306 + DB_CONNECTION: mysql + BROADCAST_DRIVER: log + CACHE_DRIVER: file + QUEUE_CONNECTION: sync + SESSION_DRIVER: file + SESSION_LIFETIME: 120 + REDIS_HOST: 127.0.0.1 + REDIS_PASSWORD: null + REDIS_PORT: 6379 + MAIL_DRIVER: smtp + MAIL_HOST: smtp.mailtrap.io + MAIL_PORT: 2525 + MAIL_USERNAME: null + MAIL_PASSWORD: null + MAIL_ENCRYPTION: null + AWS_ACCESS_KEY_ID: + AWS_SECRET_ACCESS_KEY: + AWS_DEFAULT_REGION: us-east-1 + AWS_BUCKET: + PUSHER_APP_ID: + PUSHER_APP_KEY: + PUSHER_APP_SECRET: + PUSHER_APP_CLUSTER: mt1 + MIX_PUSHER_APP_KEY: "${PUSHER_APP_KEY}" + MIX_PUSHER_APP_CLUSTER: "${PUSHER_APP_CLUSTER}" + AZURE_STORAGE_ACCOUNT: smdbstorageaccount + AZURE_STORAGE_CONTAINER: images-stage + AZURE_STORAGE_DOMAIN: blob.core.windows.net + +secrets: + dbSecretName: admin-credentials + variables: + ADMIN_USER: ADMIN_USER + ADMIN_PASSWORD: ADMIN_PASSWORD + DB_HOST: DB_HOST + DB_DATABASE: DB_DATABASE + DB_USERNAME: DB_USERNAME + DB_PASSWORD: DB_PASSWORD + APP_KEY: APP_KEY + AZURE_STORAGE_KEY: AZURE_STORAGE_KEY + AZURE_STORAGE_CONNECTION_STRING: AZURE_STORAGE_CONNECTION_STRING + +# Ingress (if using) +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + hosts: + - host: "qa.api.whatnow" + paths: + - path: / + pathType: ImplementationSpecific + - host: "api-preparemessages-stage.ifrc.org" + paths: + - path: / + pathType: Prefix + tls: + - hosts: + - "api-preparemessages-stage.ifrc.org" + secretName: "ifrc.certificates.secret"