diff --git a/.github/workflows/code-scan.yml b/.github/workflows/code-scan.yml new file mode 100644 index 0000000..5a97381 --- /dev/null +++ b/.github/workflows/code-scan.yml @@ -0,0 +1,48 @@ +name: checkov-static-analysis-scan + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + push: + branches: [ "*" ] + pull_request: + branches: [ "main" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: +permissions: read-all +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "scan" + scan: + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so follow-up steps can access it + - uses: actions/checkout@v3 + + - name: Checkov GitHub Action + uses: bridgecrewio/checkov-action@v12 + with: + # This will add both a CLI output to the console and create a results.sarif file + output_format: cli,sarif + output_file_path: console,results.sarif + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v2 + + # Results are generated only on a success or failure + # this is required since GitHub by default won't run the next step + # when the previous one has failed. Security checks that do not pass will 'fail'. + # An alternative is to add `continue-on-error: true` to the previous step + # Or 'soft_fail: true' to checkov. + if: success() || failure() + with: + sarif_file: results.sarif \ No newline at end of file diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..da2f485 --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,161 @@ +name: terraform-infra-provisioning + +on: + workflow_dispatch: + push: + branches: [ '*' ] + paths-ignore: + - '**/README.md' + pull_request: + branches: ["main"] + paths-ignore: + - '**/README.md' + +permissions: read-all +#-------------------------- +# +# PLEASE READ: Add a GitHub Actions variable 'INFRACOST_SCAN_TYPE' and set the value to either 'hcl_code' or 'tf_plan' depending on what type of Infracost scan desired. +# +#-------------------------- +jobs: + terraform: + name: 'continuous-integration' + runs-on: ubuntu-latest + environment: development + permissions: + contents: read + id-token: write + pull-requests: write + # Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest + defaults: + run: + shell: bash + + steps: + # Checkout the repository to the GitHub Actions runner + - name: Checkout + uses: actions/checkout@v3 + + - name: Configure AWS Credentials Action For GitHub Actions + uses: aws-actions/configure-aws-credentials@v1-node16 + with: + role-to-assume: ${{ secrets.IAM_ROLE }} + role-session-name: AWSSession + aws-region: us-east-2 + + - name: Setup Infracost + uses: infracost/actions/setup@v2 + if: github.event_name == 'pull_request' + # See https://github.com/infracost/actions/tree/master/setup for other inputs + # If you can't use this action, see Docker images in https://infracost.io/cicd + with: + api-key: ${{ secrets.INFRACOST_API_KEY }} + + # Checkout the base branch of the pull request (e.g. main/master). + - name: Checkout base branch + if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }} + uses: actions/checkout@v3 + with: + ref: '${{ github.event.pull_request.base.ref }}' + + # Generate Infracost JSON file as the baseline. + - name: Generate Infracost cost estimate baseline + if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }} + run: | + infracost breakdown --path=. \ + --format=json \ + --out-file=/tmp/infracost-base.json + + # Checkout the current PR branch so we can create a diff. + - name: Checkout PR branch + if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }} + uses: actions/checkout@v3 + + # Generate an Infracost diff and save it to a JSON file. + - name: Generate Infracost diff + if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }} + run: | + infracost diff --path=. \ + --format=json \ + --compare-to=/tmp/infracost-base.json \ + --out-file=/tmp/infracost.json + + # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token + - name: Setup Terraform + uses: hashicorp/setup-terraform@v1 + + # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. + - name: Terraform Init + id: init + run: terraform init + # Checks that all Terraform configuration files adhere to a canonical format + - name: Terraform Format + id: fmt + if: github.event_name == 'pull_request' + run: terraform fmt -check + # Checks that all Terraform configuration files are correctly written + - name: Terraform Validate + id: validate + if: github.event_name == 'pull_request' + run: terraform validate -no-color + # Generates an execution plan for Terraform + - name: Terraform Plan + id: plan + if: github.ref != 'refs/heads/main' || github.event_name == 'pull_request' + run: | + terraform plan -no-color -input=false -out=TFplan.JSON + continue-on-error: true + + # Generate an Infracost diff and save it to a JSON file. + - name: Generate Infracost diff + if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'tf_plan') }} + run: | + infracost diff --path=TFplan.JSON \ + --format=json \ + --out-file=/tmp/infracost.json + + - name: Post Infracost comment + if: github.event_name == 'pull_request' + run: | + infracost comment github --path=/tmp/infracost.json \ + --repo=$GITHUB_REPOSITORY \ + --github-token=${{github.token}} \ + --pull-request=${{github.event.pull_request.number}} \ + --show-skipped \ + --behavior=update + + - name: Post Terraform Plan Output + 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: | + const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\` + #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` + #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` + #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\` + +
Show Plan + + \`\`\`\n + ${process.env.PLAN} + \`\`\` + +
+ + *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }) + + # On push to "main", build or change infrastructure according to Terraform configuration files + # Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks + - name: Terraform Apply + if: github.ref == 'refs/heads/main' + run: terraform apply -auto-approve -input=false diff --git a/README.md b/README.md index e7747c6..5f55b59 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ +[![License: Unlicense](https://img.shields.io/badge/license-Unlicense-white.svg)](https://choosealicense.com/licenses/unlicense/) [![GitHub pull-requests closed](https://img.shields.io/github/issues-pr-closed/kunduso/rds-secretsmanager-rotation-lambda-terraform)](https://GitHub.com/kunduso/rds-secretsmanager-rotation-lambda-terraform/pull/) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/kunduso/rds-secretsmanager-rotation-lambda-terraform)](https://GitHub.com/kunduso/rds-secretsmanager-rotation-lambda-terraform/pull/) +[![GitHub issues-closed](https://img.shields.io/github/issues-closed/kunduso/rds-secretsmanager-rotation-lambda-terraform)](https://github.com/kunduso/rds-secretsmanager-rotation-lambda-terraform/issues?q=is%3Aissue+is%3Aclosed) [![GitHub issues](https://img.shields.io/github/issues/kunduso/rds-secretsmanager-rotation-lambda-terraform)](https://GitHub.com/kunduso/rds-secretsmanager-rotation-lambda-terraform/issues/) # terraform-rds-secretsmanager-rotation-lambda \ No newline at end of file diff --git a/backend.tf b/backend.tf new file mode 100644 index 0000000..0b5542e --- /dev/null +++ b/backend.tf @@ -0,0 +1,8 @@ +terraform { + backend "s3" { + bucket = "kunduso-terraform-remote-bucket" + encrypt = true + key = "tf/rds-secretsmanager-rotation-lambda-terraform/terraform.tfstate" + region = "us-east-2" + } +} \ No newline at end of file diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..fe2f6cb --- /dev/null +++ b/data.tf @@ -0,0 +1,3 @@ +data "aws_caller_identity" "current" {} + +data "aws_availability_zones" "available" {} \ No newline at end of file diff --git a/network.tf b/network.tf new file mode 100644 index 0000000..c77884a --- /dev/null +++ b/network.tf @@ -0,0 +1,31 @@ + +resource "aws_vpc" "this" { + #checkov:skip=CKV2_AWS_11: This is non prod and hence disabled. + cidr_block = var.vpc_cidr + enable_dns_hostnames = true + enable_dns_support = true + tags = { + "Name" = "${var.name}" + } +} +resource "aws_subnet" "db" { + count = length(var.subnet_cidr) + vpc_id = aws_vpc.this.id + cidr_block = var.subnet_cidr[count.index] + availability_zone = data.aws_availability_zones.available.names[count.index] + tags = { + "Name" = "${var.name}subnet-${count.index + 1}" + } +} +resource "aws_route_table" "this_rt" { + vpc_id = aws_vpc.this.id + tags = { + "Name" = "${var.name}-route-table" + } +} +resource "aws_route_table_association" "db" { + count = length(var.subnet_cidr) + subnet_id = element(aws_subnet.db.*.id, count.index) + route_table_id = aws_route_table.this_rt.id +} + diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..09fd349 --- /dev/null +++ b/provider.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.63.1" + } + } +} + +provider "aws" { + region = var.region + access_key = var.access_key + secret_key = var.secret_key + default_tags { + tags = { + Source = "https://github.com/kunduso/terraform-rds-secretsmanager-rotation-lambda" + } + } +} \ No newline at end of file diff --git a/security_group.tf b/security_group.tf new file mode 100644 index 0000000..2ae94b1 --- /dev/null +++ b/security_group.tf @@ -0,0 +1,4 @@ +#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_security_group +resource "aws_default_security_group" "default" { + vpc_id = aws_vpc.this.id +} \ No newline at end of file diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..a21ef38 --- /dev/null +++ b/variables.tf @@ -0,0 +1,35 @@ +#Define AWS Region +variable "region" { + description = "Infrastructure region" + type = string + default = "us-east-2" +} +#Define IAM User Access Key +variable "access_key" { + description = "The access_key that belongs to the IAM user" + type = string + sensitive = true + default = "" +} +#Define IAM User Secret Key +variable "secret_key" { + description = "The secret_key that belongs to the IAM user" + type = string + sensitive = true + default = "" +} +variable "name" { + description = "The name of the application." + type = string + default = "app-12" +} +variable "vpc_cidr" { + description = "The CIDR of the VPC." + type = string + default = "15.25.15.0/27" +} +variable "subnet_cidr" { + description = "The CIDR blocks for the subnets." + type = list(any) + default = ["12.25.15.0/28", "12.25.15.16/28"] +}