diff --git a/.github/workflows/ci-gradle.yml b/.github/workflows/ci-gradle.yml index 0b6cc7c..945ab81 100644 --- a/.github/workflows/ci-gradle.yml +++ b/.github/workflows/ci-gradle.yml @@ -1,6 +1,6 @@ name: Java CI with Gradle on: - [ push, pull_request ] + workflow_call: jobs: build_on_test: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..46cc624 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,56 @@ +name: Docker build and push +on: + workflow_call: + secrets: + DOCKERHUB_USERNAME: + required: true + + DOCKERHUB_TOKEN: + required: true + +jobs: + docker: + strategy: + matrix: + project: [ foods, orders, notifications, payment ] + + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Java 17 + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Test and Build + run: | + chmod +x gradlew + ./gradlew clean build + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v3 + + - name: Build and Push for ${{ matrix.project }} + uses: docker/build-push-action@v6 + with: + push: true + context: ./${{ matrix.project }} + file: ./${{ matrix.project }}/Dockerfile + platforms: linux/arm64,linux/amd64 + tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ matrix.project }}:latest diff --git a/.github/workflows/terraform-apply.yml b/.github/workflows/terraform-apply.yml new file mode 100644 index 0000000..ac54a91 --- /dev/null +++ b/.github/workflows/terraform-apply.yml @@ -0,0 +1,49 @@ +name: 'Terraform Apply' + +on: + push: + branches: + - main + +env: + TF_CLOUD_ORGANIZATION: "${{ secrets.TERRAFORM_ORGANISATION }}" + TF_API_TOKEN: "${{ secrets.TF_API_TOKEN }}" + TF_WORKSPACE: "${{ secrets.TF_WORKSPACE }}" + CONFIG_DIRECTORY: "./infrastructure" + +jobs: + docker-build: + uses: ./.github/workflows/docker.yml + secrets: + DOCKERHUB_USERNAME: "${{ secrets.DOCKERHUB_USERNAME }}" + DOCKERHUB_TOKEN: "${{ secrets.DOCKERHUB_TOKEN }}" + + terraform: + name: "Terraform Apply" + needs: [ docker-build ] + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Upload Configuration + uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.0.0 + id: apply-upload + with: + workspace: ${{ env.TF_WORKSPACE }} + directory: ${{ env.CONFIG_DIRECTORY }} + + - name: Create Apply Run + uses: hashicorp/tfc-workflows-github/actions/create-run@v1.0.0 + id: apply-run + with: + workspace: ${{ env.TF_WORKSPACE }} + configuration_version: ${{ steps.apply-upload.outputs.configuration_version_id }} + + - name: Wait for Manual Approval + run: | + echo "Terraform apply requires manual approval in Terraform Cloud." + echo "Go to Terraform Cloud UI to approve the apply: ${{ steps.apply-run.outputs.run_link }}" \ No newline at end of file diff --git a/.github/workflows/terraform-plan.yml b/.github/workflows/terraform-plan.yml new file mode 100644 index 0000000..bc75a4c --- /dev/null +++ b/.github/workflows/terraform-plan.yml @@ -0,0 +1,83 @@ +name: Terraform Plan +on: + [ pull_request ] + +env: + TF_CLOUD_ORGANIZATION: "${{ secrets.TERRAFORM_ORGANISATION }}" + TF_API_TOKEN: "${{ secrets.TF_API_TOKEN }}" + TF_WORKSPACE: "${{ secrets.TF_WORKSPACE }}" + CONFIG_DIRECTORY: "./infrastructure" + +jobs: + ci-gradle: + uses: ./.github/workflows/ci-gradle.yml + + terraform: + needs: [ ci-gradle ] + name: "Terraform Plan" + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Upload Configuration + uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.0.0 + id: plan-upload + with: + workspace: ${{ env.TF_WORKSPACE }} + directory: ${{ env.CONFIG_DIRECTORY }} + speculative: true + + - name: Create Plan Run + uses: hashicorp/tfc-workflows-github/actions/create-run@v1.0.0 + id: plan-run + with: + workspace: ${{ env.TF_WORKSPACE }} + configuration_version: ${{ steps.plan-upload.outputs.configuration_version_id }} + plan_only: true + + - name: Get Plan Output + uses: hashicorp/tfc-workflows-github/actions/plan-output@v1.0.0 + id: plan-output + with: + plan: ${{ fromJSON(steps.plan-run.outputs.payload).data.relationships.plan.data.id }} + + - name: Update PR + uses: actions/github-script@v6 + id: plan-comment + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + // 1. Retrieve existing bot comments for the PR + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const botComment = comments.find(comment => { + return comment.user.type === 'Bot' && comment.body.includes('HCP Terraform Plan Output') + }); + const output = `#### HCP Terraform Plan Output + \`\`\` + Plan: ${{ steps.plan-output.outputs.add }} to add, ${{ steps.plan-output.outputs.change }} to change, ${{ steps.plan-output.outputs.destroy }} to destroy. + \`\`\` + [HCP Terraform Plan](${{ steps.plan-run.outputs.run_link }}) + `; + // 3. Delete previous comment so PR timeline makes sense + if (botComment) { + github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + }); + } + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }); \ No newline at end of file diff --git a/infrastructure/main.tf b/infrastructure/main.tf new file mode 100644 index 0000000..24ed1f5 --- /dev/null +++ b/infrastructure/main.tf @@ -0,0 +1,16 @@ +resource "aws_iam_group" "developers" { + name = "developers" +} + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +provider "aws" { + region = "eu-west-2" +} \ No newline at end of file