diff --git a/.github/workflows/deploy-k8s.yml b/.github/workflows/deploy-k8s.yml index c8ff0bd..9d0a00d 100644 --- a/.github/workflows/deploy-k8s.yml +++ b/.github/workflows/deploy-k8s.yml @@ -37,10 +37,10 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4.1.0 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1 + uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -48,7 +48,7 @@ jobs: aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} # optional - name: use awscli - uses: unfor19/install-aws-cli-action@master + uses: unfor19/install-aws-cli-action@46282f151073130d90347412d9c4ef0640177f22 with: version: 2 @@ -59,7 +59,7 @@ jobs: id: kubeconfig run: | echo "::add-mask::$(aws eks --region ${{ inputs.aws_region }} update-kubeconfig --name ${{ inputs.k8s_cluster_name }} --dry-run | base64 -w 0)" - echo "::set-output name=KUBECONFIG::$(aws eks --region ${{ inputs.aws_region }} update-kubeconfig --name ${{ inputs.k8s_cluster_name }} --dry-run | base64 -w 0)" + echo "KUBECONFIG=$(aws eks --region ${{ inputs.aws_region }} update-kubeconfig --name ${{ inputs.k8s_cluster_name }} --dry-run | base64 -w 0)" >> $GITHUB_OUTPUT shell: bash - name: Generate k8s secret params @@ -71,7 +71,7 @@ jobs: echo "result: ${{ inputs.ci_env }}_ENV_VARS" for i in `cat .github/workflows/ci-properties.json | jq -r .${{ inputs.ci_env }}_ENV_VARS | jq -r 'keys[]' || true`; do params="${params} --from-literal=$i=$(cat .github/workflows/ci-properties.json | jq -r .${{ inputs.ci_env }}_ENV_VARS.$i)"; done echo "ENV VARS from ci-properties.json: $params" - echo "::set-output name=k8sparams::$params" + echo "k8sparams=$params" >> $GITHUB_OUTPUT - name: print k8sparams id: print @@ -79,7 +79,7 @@ jobs: echo "${{ steps.genparams.outputs.k8sparams }}" - name: Create kubernetes secret with service parameters - uses: kodermax/kubectl-aws-eks@master + uses: kodermax/kubectl-aws-eks@7e223308593f74c42b45782d230783715e131d51 env: KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} KUBECTL_VERSION: "v1.22.0" @@ -90,10 +90,10 @@ jobs: - name: Generate k8s secret params shell: bash run: | - sed -i 's|image: ${{ inputs.IMAGE_NAME }}|image: ${{ inputs.IMAGE_NAME }}:${{ inputs.KUBE_NAMESPACE }}|' deployment.yaml + sed -i 's|${{ inputs.IMAGE_NAME }}|${{ inputs.IMAGE_NAME }}:${{ inputs.KUBE_NAMESPACE }}|' deployment.yaml - name: kubernets apply config - uses: kodermax/kubectl-aws-eks@master + uses: kodermax/kubectl-aws-eks@7e223308593f74c42b45782d230783715e131d51 env: KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} KUBECTL_VERSION: "v1.22.0" @@ -102,10 +102,24 @@ jobs: args: apply -f deployment.yaml -n ${{ inputs.KUBE_NAMESPACE }} - name: rollout - uses: kodermax/kubectl-aws-eks@master + uses: kodermax/kubectl-aws-eks@7e223308593f74c42b45782d230783715e131d51 env: KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} KUBECTL_VERSION: "v1.22.0" IAM_VERSION: "0.5.6" with: args: rollout restart deploy/${{ inputs.app_name }} -n ${{ inputs.KUBE_NAMESPACE }} + + - name: Template ingress (optional) + shell: bash + run: | + sed -i "s|host: ingress.hostname|host: $(cat .github/workflows/ci-properties.json | jq -r .${{ inputs.ci_env }}_ENV_VARS.INGRESS_HOSTNAME)|" ingress.yaml || true + + - name: apply ingress (optional) + uses: kodermax/kubectl-aws-eks@7e223308593f74c42b45782d230783715e131d51 + env: + KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} + KUBECTL_VERSION: "v1.22.0" + IAM_VERSION: "0.5.6" + with: + args: apply -f ingress.yaml -n ${{ inputs.KUBE_NAMESPACE }} || true diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9a6235a..870d4a0 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -10,17 +10,22 @@ on: event_name: required: true type: string - registry: + dockerfile_path: required: true type: string - dockerfile_path: + registry: + required: false + type: string + aws_region: required: true type: string secrets: - DOCKER_USERNAME: + AWS_ACCESS_KEY_ID: required: true - DOCKER_PASSWORD: + AWS_SECRET_ACCESS_KEY: required: true + AWS_SESSION_TOKEN: + required: false jobs: build: @@ -28,36 +33,30 @@ jobs: permissions: contents: read packages: write - steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4.1.0 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ inputs.aws_region }} + aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} # optional + mask-aws-account-id: 'no' - # Login against a Docker registry except on PR - # https://github.com/docker/login-action - name: Login to registry ${{ inputs.registry }} if: inputs.event_name != 'pull_request' - uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c - with: - registry: ${{ inputs.registry }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - - name: Extract Docker metadata - id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + uses: docker/login-action@v2 with: - images: ${{ inputs.registry }}/${{ inputs.IMAGE_NAME }} + registry: ${{ inputs.registry }} - # Build and push Docker image with Buildx (don't push on PR) - # https://github.com/docker/build-push-action - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + uses: docker/build-push-action@v5.0.0 with: context: . file: ${{ inputs.dockerfile_path }}/Dockerfile push: ${{ inputs.event_name != 'pull_request' }} tags: ${{ inputs.registry }}/${{ inputs.IMAGE_NAME }}:${{ inputs.KUBE_NAMESPACE }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 133422c..7964237 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -40,7 +40,7 @@ jobs: dockerfile_path: ${{ steps.setvars.outputs.dockerfile_path }} steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v4.1.0 - name: Read repo properties shell: bash @@ -55,16 +55,16 @@ jobs: id: setvars run: | if [[ "${{ inputs.base_ref }}" == "${{ env.prod_branch }}" || "${{ inputs.ref }}" == "refs/heads/${{ env.prod_branch }}" ]]; then - echo "::set-output name=k8s_namespace::production" - echo "::set-output name=ci_env::PROD" + echo "k8s_namespace=production" >> $GITHUB_OUTPUT + echo "ci_env=PROD" >> $GITHUB_OUTPUT fi if [[ "${{ inputs.base_ref }}" == "${{ env.dev_branch }}" || "${{ inputs.ref }}" == "refs/heads/${{ env.dev_branch }}" ]]; then - echo "::set-output name=k8s_namespace::test" - echo "::set-output name=ci_env::DEV" + echo "k8s_namespace=test" >> $GITHUB_OUTPUT + echo "ci_env=DEV" >> $GITHUB_OUTPUT fi - echo "::set-output name=image_name::${{ env.image_name }}" - echo "::set-output name=registry::${{ env.registry }}" - echo "::set-output name=aws_region::${{ env.aws_region }}" - echo "::set-output name=k8s_cluster_name::${{ env.k8s_cluster_name }}" - echo "::set-output name=app_name::${{ env.app_name }}" - echo "::set-output name=dockerfile_path::${{ env.dockerfile_path }}" + echo "image_name=${{ env.image_name }}" >> $GITHUB_OUTPUT + echo "registry=${{ env.registry }}" >> $GITHUB_OUTPUT + echo "aws_region=${{ env.aws_region }}" >> $GITHUB_OUTPUT + echo "k8s_cluster_name=${{ env.k8s_cluster_name }}" >> $GITHUB_OUTPUT + echo "app_name=${{ env.app_name }}" >> $GITHUB_OUTPUT + echo "dockerfile_path=${{ env.dockerfile_path }}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/migration-k8s.yml b/.github/workflows/migration-k8s.yml new file mode 100644 index 0000000..54667e0 --- /dev/null +++ b/.github/workflows/migration-k8s.yml @@ -0,0 +1,115 @@ +on: + workflow_call: + inputs: + IMAGE_NAME: + required: true + type: string + KUBE_NAMESPACE: + required: true + type: string + event_name: + required: true + type: string + dockerfile_path: + required: true + type: string + registry: + required: true + type: string + aws_region: + required: true + type: string + k8s_cluster_name: + required: true + type: string + app_name: + required: true + type: string + secrets: + AWS_ACCESS_KEY_ID: + required: true + AWS_SECRET_ACCESS_KEY: + required: true + AWS_SESSION_TOKEN: + required: false + + +jobs: + deploy: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4.1.0 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ inputs.aws_region }} + aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }} # optional + + - name: Login to registry ${{ inputs.registry }} + if: inputs.event_name != 'pull_request' + uses: docker/login-action@v2 + with: + registry: ${{ inputs.registry }} + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ${{ inputs.dockerfile_path }}/Dockerfile-dev + push: ${{ inputs.event_name != 'pull_request' }} + tags: ${{ inputs.registry }}/${{ inputs.IMAGE_NAME }}:${{ inputs.KUBE_NAMESPACE }}Migration + + - name: use awscli + uses: unfor19/install-aws-cli-action@master + with: + version: 2 + + - run: aws --version + shell: bash + + - name: login to EKS + id: kubeconfig + run: | + echo "::add-mask::$(aws eks --region ${{ inputs.aws_region }} update-kubeconfig --name ${{ inputs.k8s_cluster_name }} --dry-run | base64 -w 0)" + echo "KUBECONFIG=$(aws eks --region ${{ inputs.aws_region }} update-kubeconfig --name ${{ inputs.k8s_cluster_name }} --dry-run | base64 -w 0)" >> $GITHUB_OUTPUT + shell: bash + + - name: Generate k8s secret params + shell: bash + run: | + sed -i 's|${{ inputs.IMAGE_NAME }}|${{ inputs.IMAGE_NAME }}:${{ inputs.KUBE_NAMESPACE }}Migration|' migration.yaml + + - name: kubernets run migration + uses: kodermax/kubectl-aws-eks@214195db51c87cdd4d7c1e33e43f7638b5849186 + env: + KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} + KUBECTL_VERSION: "v1.22.0" + IAM_VERSION: "0.5.6" + with: + args: apply -f migration.yaml -n ${{ inputs.KUBE_NAMESPACE }} + + - name: kubernets wair for migration to end + uses: kodermax/kubectl-aws-eks@214195db51c87cdd4d7c1e33e43f7638b5849186 + env: + KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} + KUBECTL_VERSION: "v1.22.0" + IAM_VERSION: "0.5.6" + with: + args: wait --for=condition=complete job/${{ inputs.app_name }}-migration -n ${{ inputs.KUBE_NAMESPACE }} + + - name: kubernets wair for migration to end + uses: kodermax/kubectl-aws-eks@214195db51c87cdd4d7c1e33e43f7638b5849186 + env: + KUBE_CONFIG_DATA: ${{ steps.kubeconfig.outputs.KUBECONFIG }} + KUBECTL_VERSION: "v1.22.0" + IAM_VERSION: "0.5.6" + with: + args: delete job ${{ inputs.app_name }}-migration -n ${{ inputs.KUBE_NAMESPACE }} diff --git a/workflow-templates/ci-cd-development.yml b/workflow-templates/ci-cd-development.yml index f144c7d..5362bab 100644 --- a/workflow-templates/ci-cd-development.yml +++ b/workflow-templates/ci-cd-development.yml @@ -23,6 +23,24 @@ jobs: secrets: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + call-workflow-k8s-migration: + needs: [call-workflow-init, call-workflow-docker-build] + if: github.event_name != 'pull_request' + uses: DistributedCollective/.github/.github/workflows/migration-k8s.yml@master # in case additional secrets is needed, this file must be changed and pushed to your repository + with: + IMAGE_NAME: ${{ needs.call-workflow-init.outputs.image_name }} + KUBE_NAMESPACE: ${{ needs.call-workflow-init.outputs.KUBE_NAMESPACE }} + aws_region: ${{ needs.call-workflow-init.outputs.aws_region }} + k8s_cluster_name: ${{ needs.call-workflow-init.outputs.k8s_cluster_name }} + app_name: ${{ needs.call-workflow-init.outputs.app_name }} + event_name: ${{ github.event_name }} + registry: ${{ needs.call-workflow-init.outputs.registry }} + dockerfile_path: ${{ needs.call-workflow-init.outputs.dockerfile_path }} + secrets: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }} # optional + # addional secrets must me defined here call-workflow-k8s-deploy: needs: [call-workflow-init, call-workflow-docker-build] if: github.event_name != 'pull_request' @@ -30,6 +48,7 @@ jobs: with: IMAGE_NAME: ${{ needs.call-workflow-init.outputs.image_name }} KUBE_NAMESPACE: ${{ needs.call-workflow-init.outputs.KUBE_NAMESPACE }} + ci_env: ${{ needs.call-workflow-init.outputs.ci_env }} aws_region: ${{ needs.call-workflow-init.outputs.aws_region }} k8s_cluster_name: ${{ needs.call-workflow-init.outputs.k8s_cluster_name }} app_name: ${{ needs.call-workflow-init.outputs.app_name }}