Skip to content

Commit

Permalink
Merge pull request #48 from NHSDigital/CCM-8478_TFSec-HardFail
Browse files Browse the repository at this point in the history
CCM-8478 tf sec hard fail
  • Loading branch information
aidenvaines-bjss authored Jan 30, 2025
2 parents dd543a7 + 0248698 commit 1261374
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/actions/create-lines-of-code-report/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ runs:
run: zip lines-of-code-report.json.zip lines-of-code-report.json
- name: "Upload CLOC report as an artefact"
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: lines-of-code-report.json.zip
path: ./lines-of-code-report.json.zip
Expand Down
4 changes: 2 additions & 2 deletions .github/actions/scan-dependencies/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ runs:
run: zip sbom-repository-report.json.zip sbom-repository-report.json
- name: "Upload SBOM report as an artefact"
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: sbom-repository-report.json.zip
path: ./sbom-repository-report.json.zip
Expand All @@ -47,7 +47,7 @@ runs:
run: zip vulnerabilities-repository-report.json.zip vulnerabilities-repository-report.json
- name: "Upload vulnerabilities report as an artefact"
if: ${{ !env.ACT }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: vulnerabilities-repository-report.json.zip
path: ./vulnerabilities-repository-report.json.zip
Expand Down
19 changes: 10 additions & 9 deletions .github/actions/tfsec/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ runs:
- name: "TFSec Scan - Components"
shell: bash
run: |
for component in $(find infrastructure/terraform/components -mindepth 1 -type d); do
scripts/terraform/tfsec.sh $component
done
- name: "TFSec Scan - Modules"
shell: bash
run: |
for module in $(find infrastructure/terraform/modules -mindepth 1 -type d); do
scripts/terraform/tfsec.sh $module
done
components_exit_code=0
modules_exit_code=0
./scripts/terraform/tfsec.sh ./infrastructure/terraform/components || components_exit_code=$?
./scripts/terraform/tfsec.sh ./infrastructure/terraform/modules || modules_exit_code=$?
if [ $components_exit_code -ne 0 ] || [ $modules_exit_code -ne 0 ]; then
echo "One or more TFSec scans failed."
exit 1
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
resource "aws_iam_policy" "github_deploy_overload" {
name = "${local.csi}-github-deploy-overload"
description = "Overloads the github permission to perform build actions for services in this account"
policy = data.aws_iam_policy_document.github_deploy.json
}

resource "aws_iam_role_policy_attachment" "github_deploy_overload" {
role = local.bootstrap.iam_github_deploy_role["name"]
policy_arn = aws_iam_policy.github_deploy_overload.arn
}

#tfsec:ignore:aws-iam-no-policy-wildcards Policy voilation expected for CI user role
data "aws_iam_policy_document" "github_deploy" {
statement {
effect = "Allow"

actions = [
"grafana:*",
]
resources = ["*"]
}
}
21 changes: 21 additions & 0 deletions infrastructure/terraform/components/acct/locals_remote_state.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
locals {
bootstrap = data.terraform_remote_state.bootstrap.outputs
}

data "terraform_remote_state" "bootstrap" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/bootstrap.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
"bootstrap"
)

region = "eu-west-2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
locals {
bootstrap = data.terraform_remote_state.bootstrap.outputs
acct = data.terraform_remote_state.acct.outputs
}

data "terraform_remote_state" "bootstrap" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/bootstrap.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
"bootstrap"
)

region = "eu-west-2"
}
}

data "terraform_remote_state" "acct" {
backend = "s3"

config = {
bucket = local.terraform_state_bucket

key = format(
"%s/%s/%s/%s/acct.tfstate",
var.project,
var.aws_account_id,
"eu-west-2",
var.parent_acct_environment
)

region = "eu-west-2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
locals {
terraform_state_bucket = format(
"%s-tfscaffold-%s-%s",
var.project,
var.aws_account_id,
var.region,
)

csi = replace(
format(
"%s-%s-%s",
var.project,
var.environment,
var.component,
),
"_",
"",
)

# CSI for use in resources with a global namespace, i.e. S3 Buckets
csi_global = replace(
format(
"%s-%s-%s-%s-%s",
var.project,
var.aws_account_id,
var.region,
var.environment,
var.component,
),
"_",
"",
)

default_tags = merge(
var.default_tags,
{
Project = var.project
Environment = var.environment
Component = var.component
Group = var.group
Name = local.csi
},
)
}
Original file line number Diff line number Diff line change
@@ -1 +1,58 @@
# Define the variables that will be initialised in etc/{env,versions}_<region>_<environment>.tfvars...
##
# Basic Required Variables for tfscaffold Components
##

variable "project" {
type = string
description = "The name of the tfscaffold project"
}

variable "environment" {
type = string
description = "The name of the tfscaffold environment"
}

variable "aws_account_id" {
type = string
description = "The AWS Account ID (numeric)"
}

variable "region" {
type = string
description = "The AWS Region"
}

variable "group" {
type = string
description = "The group variables are being inherited from (often synonmous with account short-name)"
}

##
# tfscaffold variables specific to this component
##

# This is the only primary variable to have its value defined as
# a default within its declaration in this file, because the variables
# purpose is as an identifier unique to this component, rather
# then to the environment from where all other variables come.
variable "component" {
type = string
description = "The variable encapsulating the name of this component"
default = "examplecomponent"
}

variable "default_tags" {
type = map(string)
description = "A map of default tags to apply to all taggable resources within the component"
default = {}
}

##
# Variables specific to the component
##

variable "log_retention_in_days" {
type = number
description = "The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite"
default = 0
}
2 changes: 1 addition & 1 deletion scripts/terraform/terraform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ terraform-sec: # TFSEC check against Terraform files - optional: terraform_dir|d
--exclude-downloaded-modules \
--tfvars-file infrastructure/terraform/etc/global.tfvars \
--tfvars-file infrastructure/terraform/etc/env_eu-west-2_main.tfvars \
--config-file scripts/config/tfsec.yml
--config-file scripts/config/tfsec.yaml

# ==============================================================================
# Module tests and examples - please DO NOT edit this section!
Expand Down
2 changes: 0 additions & 2 deletions scripts/terraform/tfsec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,10 @@ function run-tfsec-natively() {

echo "Running TFSec on directory: $dir_to_scan"
tfsec \
--concise-output \
--force-all-dirs \
--exclude-downloaded-modules \
--config-file scripts/config/tfsec.yaml \
--format text \
--soft-fail \
"$dir_to_scan"

check-tfsec-status
Expand Down

0 comments on commit 1261374

Please sign in to comment.