diff --git a/.github/workflows/master.yml b/.github/workflows/prow.yml similarity index 85% rename from .github/workflows/master.yml rename to .github/workflows/prow.yml index c2814d5aed2..5e758116e48 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/prow.yml @@ -1,4 +1,4 @@ -name: Master CI - deploys terraform and prow +name: Deploy Prow on: push: @@ -24,10 +24,6 @@ jobs: role-to-assume: "arn:aws:iam::292999226676:role/github_actions-test-infra-cluster" aws-region: eu-west-1 - - name: Deploy terraform - run: | - ./tools/deploy_terraform.sh - - name: Deploy prow env: PROW_HMAC_TOKEN: ${{ secrets.PROW_HMAC_TOKEN }} diff --git a/.github/workflows/terraform-apply.yml b/.github/workflows/terraform-apply.yml new file mode 100644 index 00000000000..94f87dc9e54 --- /dev/null +++ b/.github/workflows/terraform-apply.yml @@ -0,0 +1,49 @@ +name: Terraform apply + +on: + push: + branches: + - master + paths: + - 'config/clusters/**' + +concurrency: + group: master-CI + cancel-in-progress: false + +defaults: + run: + working-directory: config/clusters + +jobs: + plan: + permissions: + id-token: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: hashicorp/setup-terraform@v2 + + - name: Configure AWS credentials ๐Ÿ”งโš™๏ธ + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: "arn:aws:iam::292999226676:role/github_actions-test-infra-cluster" + aws-region: eu-west-1 + + - name: Terraform fmt + id: fmt + run: terraform fmt -check + continue-on-error: true + + - name: Terraform Init + id: init + run: terraform init + + - name: Terraform Validate + id: validate + run: terraform validate -no-color + + - name: Terraform Apply + id: apply + run: terraform apply -auto-approve + diff --git a/.github/workflows/terraform-plan.yml b/.github/workflows/terraform-plan.yml new file mode 100644 index 00000000000..63179acf9e3 --- /dev/null +++ b/.github/workflows/terraform-plan.yml @@ -0,0 +1,116 @@ +name: Terraform plan + +on: + pull_request: + branches: + - master + paths: + - 'config/clusters/**' + +defaults: + run: + working-directory: config/clusters + +jobs: + plan: + permissions: + pull-requests: write + id-token: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: hashicorp/setup-terraform@v2 + + - name: Configure AWS credentials ๐Ÿ”งโš™๏ธ + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: "arn:aws:iam::292999226676:role/github_actions-test-infra-reader" + aws-region: eu-west-1 + + - name: Terraform fmt + id: fmt + run: terraform fmt -check + continue-on-error: true + + - name: Terraform Init + id: init + run: terraform init + + - name: Terraform Validate + id: validate + run: terraform validate -no-color + + - name: Run Terrascan + id: terrascan + uses: tenable/terrascan-action@v1.4.1 + with: + iac_type: terraform + iac_version: v14 + policy_type: aws + only_warn: true + + - name: Terraform Plan + id: plan + run: terraform plan -no-color + continue-on-error: true + + - name: Update PR + id: plan-comment + uses: actions/github-script@v6 + if: github.event_name == 'pull_request' + env: + PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" + 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('Terraform Format and Style') + }) + + // 2. Prepare format of the comment + const output = `#### Terraform Format and Style ๐Ÿ–Œ\`${{ steps.fmt.outcome }}\` + #### Terraform Initialization โš™๏ธ\`${{ steps.init.outcome }}\` + #### Terraform Validation ๐Ÿค–\`${{ steps.validate.outcome }}\` +
Validation Output + + \`\`\`\n + ${{ steps.validate.outputs.stdout }} + \`\`\` + +
+ + #### Terraform Plan ๐Ÿ“–\`${{ steps.plan.outcome }}\` + +
Show Plan + + \`\`\`\n + ${process.env.PLAN} + \`\`\` + +
+ + *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Working Directory: \`${{ env.tf_actions_working_dir }}\`, Workflow: \`${{ github.workflow }}\`*`; + + // 3. If we have a comment, update it, otherwise create a new one + if (botComment) { + github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: output + }) + } else { + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }) + } + diff --git a/config/clusters/iam.tf b/config/clusters/iam.tf index cf0b7e62013..c58f66e84dc 100644 --- a/config/clusters/iam.tf +++ b/config/clusters/iam.tf @@ -266,10 +266,31 @@ module "test-infra_reader" { name = "github_actions-test-infra-reader" create = true subjects = [ - "falcosecurity/test-infra:ref:refs/heads/*" + "falcosecurity/test-infra:ref:*" ] policies = { test-infra_read_access = "arn:aws:iam::aws:policy/ReadOnlyAccess" + test-infra_state_lock = "${aws_iam_policy.test-infra_state_lock.arn}" + } +} + +resource "aws_iam_policy" "test-infra_state_lock" { + name_prefix = "github_actions-test-infra-cluster" + description = "Access policy for test-infra Terraform remote state lock" + policy = data.aws_iam_policy_document.test-infra_state_lock.json +} + +data "aws_iam_policy_document" "test-infra_state_lock" { + statement { + sid = "DeployTestInfraClusterAccess" + effect = "Allow" + actions = [ + "dynamodb:PutItem", + "dynamodb:DeleteItem" + ] + resources = [ + "arn:aws:dynamodb:::table/${var.state_dynamodb_table_name}" + ] } } diff --git a/config/clusters/iam_variables.tf b/config/clusters/iam_variables.tf new file mode 100644 index 00000000000..5d6043dc2f8 --- /dev/null +++ b/config/clusters/iam_variables.tf @@ -0,0 +1,5 @@ +variable "state_dynamodb_table_name" { + type = string + description = "The name of the DynamoDB table for the Terraform state" + default = "falco-test-infra-state-lock" +} diff --git a/config/clusters/prow.tfvars b/config/clusters/prow.auto.tfvars similarity index 70% rename from config/clusters/prow.tfvars rename to config/clusters/prow.auto.tfvars index fca7ce898d1..c704537fd34 100644 --- a/config/clusters/prow.tfvars +++ b/config/clusters/prow.auto.tfvars @@ -13,3 +13,17 @@ eks_default_worker_group_asg_desired_capacity = 3 eks_default_worker_group_asg_max_capacity = 10 eks_jobs_worker_group_asg_max_capacity = 20 eks_jobs_arm_worker_group_asg_max_capacity = 20 + +eks_roles = [ + { + rolearn = "arn:aws:iam::292999226676:role/github_actions-test-infra-cluster" + username = "githubactions-test-infra-cluster" + groups = ["system:masters"] + }, + { + rolearn = "arn:aws:iam::292999226676:role/github_actions-test-infra-reader" + username = "githubactions-test-infra-reader" + groups = ["aws-config-readers"] + }, +] + diff --git a/tools/deploy_terraform.sh b/tools/deploy_terraform.sh deleted file mode 100755 index adf404b67cc..00000000000 --- a/tools/deploy_terraform.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: Apache-2.0 -# -# Copyright (C) 2023 The Falco Authors. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -set -o nounset -set -o pipefail - -# Specific to Prow instance -PROW_INSTANCE_NAME="${PROW_INSTANCE_NAME:-}" -CLUSTER="falco-prow" -ZONE="eu-west-1" - -function main() { - echo "> Installing terraform" - echo - terraform-install - echo "> Running Terraform" - echo - createCluster -} - -function terraform-install() { - hash terraform 2>/dev/null && \ - echo "Already installed at $(command -v terraform)." && \ - echo "Version: $(terraform version)" && \ - return 0 - - local terraform_version=$(grep required_version config/clusters/terraform_versions.tf | cut -d '=' -f3 | tr -d '"' | tr -d ' ') - local terraform_url="https://releases.hashicorp.com/terraform/${terraform_version}/terraform_${terraform_version}_linux_amd64.zip" - local install_path="/usr/local/bin/" - local tmpdir=$(mktemp -d) - - curl -s "${terraform_url}" > $tmpdir/terraform.zip - unzip $tmpdir/terraform.zip - rm -rf $tmpdir - install terraform $install_path - terraform --version - echo "Installed: $(terraform)" -} - -function createCluster() { - echo "Creating cluster '${CLUSTER}' (this may take a few minutes)..." - echo - - pushd config/clusters - - terraform init - terraform get - terraform validate - - terraform apply -var-file prow.tfvars -auto-approve - - popd - - aws eks --region ${ZONE} update-kubeconfig --name falco-prow-test-infra -} - -function cleanup() { - returnCode="$?" - exit "${returnCode}" -} - -trap cleanup EXIT -main "$@" -cleanup