diff --git a/.github/workflows/quality_checks.yml b/.github/workflows/quality_checks.yml index d7616d42d..268b5423e 100644 --- a/.github/workflows/quality_checks.yml +++ b/.github/workflows/quality_checks.yml @@ -58,6 +58,20 @@ jobs: - name: run unit tests run: make test + - name: Run cfn-guard + run: make cfn-guard + + - name: show cfn-guard output + if: failure() + run: find cfn_guard_output -type f -print0 | xargs -0 cat + + - uses: actions/upload-artifact@v4 + name: upload cfn_guard_output + if: failure() + with: + name: cfn_guard_output + path: cfn_guard_output + - name: SonarCloud Scan uses: SonarSource/sonarcloud-github-action@master env: diff --git a/.gitignore b/.gitignore index d3d657c26..5de2e51cb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,9 @@ release_notes .aws-sam lib/ *.tsbuildinfo +cfn_guard_output/ _site/ .sass-cache .jekyll-cache .jekyll-metadata -vendor \ No newline at end of file +vendor diff --git a/Makefile b/Makefile index 6dc06a066..8e9d2c0e3 100644 --- a/Makefile +++ b/Makefile @@ -190,3 +190,6 @@ aws-configure: aws-login: aws sso login --sso-session sso-session + +cfn-guard: + ./scripts/run_cfn_guard.sh diff --git a/README.md b/README.md index 808098611..3deee8ca1 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,7 @@ These are used to do common commands - `lint-cloudformation` runs lint for cloudformation templates - `lint-samtemplates` runs lint for SAM templates - `test` runs unit tests for all code +- `cfn-guard` runs cfn-guard for sam and cloudformation templates #### Compiling diff --git a/SAMtemplates/apis/api_resources.yaml b/SAMtemplates/apis/api_resources.yaml index cdade1bf2..af4b75768 100644 --- a/SAMtemplates/apis/api_resources.yaml +++ b/SAMtemplates/apis/api_resources.yaml @@ -1,4 +1,4 @@ -AWSTemplateFormatVersion: '2010-09-09' +AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: | Resources for an API @@ -8,14 +8,14 @@ Parameters: Type: CommaDelimitedList Description: A list of additional policies to attach to the API gateway role (comma delimited). Default: none - + ApiName: Type: String Default: none - + LogRetentionInDays: Type: Number - + EnableSplunk: Type: String @@ -38,35 +38,38 @@ Resources: Action: - sts:AssumeRole ManagedPolicyArns: !Split - - ',' + - "," - !Join - - ',' + - "," - - !Join - - ',' + - "," - !Ref AdditionalPolicies - ApiGwAccessLogs: Type: AWS::Logs::LogGroup + Metadata: + guard: + SuppressedRules: + - CW_LOGGROUP_RETENTION_PERIOD_CHECK Properties: LogGroupName: !Sub /aws/apigateway/${ApiName} RetentionInDays: !Ref LogRetentionInDays KmsKeyId: !ImportValue account-resources:CloudwatchLogsKmsKeyArn - + ApiGwAccessLogsSplunkSubscriptionFilter: Condition: ShouldUseSplunk Type: AWS::Logs::SubscriptionFilter Properties: RoleArn: !ImportValue lambda-resources:SplunkSubscriptionFilterRole LogGroupName: !Ref ApiGwAccessLogs - FilterPattern: '' + FilterPattern: "" DestinationArn: !ImportValue lambda-resources:SplunkDeliveryStream Outputs: ApiGwRoleArn: Description: The API GW role ARN Value: !GetAtt ApiGwRole.Arn - + ApiGwAccessLogsArn: Description: The API GW access logs ARN Value: !GetAtt ApiGwAccessLogs.Arn diff --git a/SAMtemplates/functions/lambda_resources.yaml b/SAMtemplates/functions/lambda_resources.yaml index 2c12eac82..863d9f1b8 100644 --- a/SAMtemplates/functions/lambda_resources.yaml +++ b/SAMtemplates/functions/lambda_resources.yaml @@ -10,34 +10,34 @@ Parameters: LambdaName: Type: String Default: none - + LambdaArn: Type: String Default: none - + IncludeAdditionalPolicies: Type: String Default: false - + AdditionalPolicies: Type: CommaDelimitedList Description: A list of additional policies to attach the lambdas role (comma delimited). Default: none - + LogRetentionInDays: Type: Number - + CloudWatchKMSKeyId: Type: String Default: none - + EnableSplunk: Type: String - + SplunkSubscriptionFilterRole: Type: String Default: none - + SplunkDeliveryStreamArn: Type: String Default: none @@ -46,7 +46,7 @@ Conditions: ShouldUseSplunk: !Equals - true - !Ref EnableSplunk - + ShouldIncludeAdditionalPolicies: !Equals - true - !Ref IncludeAdditionalPolicies @@ -103,21 +103,25 @@ Resources: Resource: - !GetAtt LambdaLogGroup.Arn - !Sub ${LambdaLogGroup.Arn}:log-stream:* - + LambdaLogGroup: Type: AWS::Logs::LogGroup + Metadata: + guard: + SuppressedRules: + - CW_LOGGROUP_RETENTION_PERIOD_CHECK Properties: LogGroupName: !Sub /aws/lambda/${LambdaName} RetentionInDays: !Ref LogRetentionInDays KmsKeyId: !Ref CloudWatchKMSKeyId - + LambdaSplunkSubscriptionFilter: Condition: ShouldUseSplunk Type: AWS::Logs::SubscriptionFilter Properties: RoleArn: !Ref SplunkSubscriptionFilterRole LogGroupName: !Ref LambdaLogGroup - FilterPattern: '' + FilterPattern: "" DestinationArn: !Ref SplunkDeliveryStreamArn Outputs: diff --git a/SAMtemplates/functions/main.yaml b/SAMtemplates/functions/main.yaml index 1e2094203..cd621740a 100644 --- a/SAMtemplates/functions/main.yaml +++ b/SAMtemplates/functions/main.yaml @@ -78,6 +78,11 @@ Resources: - !Ref GetSecretsLayer Metadata: BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: es2020 @@ -118,6 +123,11 @@ Resources: EXPECT_STATUS_UPDATES: !Ref ToggleGetStatusUpdates Metadata: BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: es2020 @@ -150,6 +160,11 @@ Resources: Role: !GetAtt CapabilityStatementResources.Outputs.LambdaRoleArn Metadata: BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: es2020 @@ -189,6 +204,11 @@ Resources: - !Ref GetSecretsLayer Metadata: BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: es2020 diff --git a/SAMtemplates/sandbox_template.yaml b/SAMtemplates/sandbox_template.yaml index 35ba361e4..76e36b7e9 100644 --- a/SAMtemplates/sandbox_template.yaml +++ b/SAMtemplates/sandbox_template.yaml @@ -127,6 +127,11 @@ Resources: Method: get Metadata: # Manage esbuild properties BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: es2020 @@ -167,6 +172,11 @@ Resources: Method: get Metadata: # Manage esbuild properties BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: es2020 @@ -211,6 +221,11 @@ Resources: Method: get Metadata: # Manage esbuild properties BuildMethod: esbuild + guard: + SuppressedRules: + - LAMBDA_DLQ_CHECK + - LAMBDA_INSIDE_VPC + - LAMBDA_CONCURRENCY_CHECK BuildProperties: Minify: true Target: "es2020" @@ -319,6 +334,10 @@ Resources: ApiGwAccessLogs: Type: AWS::Logs::LogGroup + Metadata: + guard: + SuppressedRules: + - CW_LOGGROUP_RETENTION_PERIOD_CHECK Properties: LogGroupName: !Join [ diff --git a/SAMtemplates/state_machines/state_machine_resources.yaml b/SAMtemplates/state_machines/state_machine_resources.yaml index d5c163219..0d46507a7 100644 --- a/SAMtemplates/state_machines/state_machine_resources.yaml +++ b/SAMtemplates/state_machines/state_machine_resources.yaml @@ -111,6 +111,10 @@ Resources: StateMachineLogGroup: Type: AWS::Logs::LogGroup + Metadata: + guard: + SuppressedRules: + - CW_LOGGROUP_RETENTION_PERIOD_CHECK Properties: LogGroupName: !Sub /aws/stepfunctions/${StateMachineName} RetentionInDays: !Ref LogRetentionInDays diff --git a/scripts/run_cfn_guard.sh b/scripts/run_cfn_guard.sh new file mode 100755 index 000000000..fd4434c02 --- /dev/null +++ b/scripts/run_cfn_guard.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -eou pipefail + +rm -rf /tmp/ruleset +rm -rf cfn_guard_output + +wget -O /tmp/ruleset.zip https://github.com/aws-cloudformation/aws-guard-rules-registry/releases/download/1.0.2/ruleset-build-v1.0.2.zip >/dev/null 2>&1 +unzip /tmp/ruleset.zip -d /tmp/ruleset/ >/dev/null 2>&1 + +curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh >/dev/null 2>&1 + +mkdir -p cfn_guard_output + +declare -a rulesets=("ncsc" "ncsc-cafv3" "wa-Reliability-Pillar" "wa-Security-Pillar") +for ruleset in "${rulesets[@]}" +do + while IFS= read -r -d '' file + do + echo "checking SAM template $file with ruleset $ruleset" + mkdir -p "$(dirname cfn_guard_output/"$file")" + + SAM_OUPUT=$(sam validate -t "$file" --region eu-west-2 --debug 2>&1 | \ + grep -Pazo '(?s)AWSTemplateFormatVersion.*\n\/' | tr -d '\0') + echo "${SAM_OUPUT::-1}" | ~/.guard/bin/cfn-guard validate \ + --rules "/tmp/ruleset/output/$ruleset.guard" \ + --show-summary fail \ + > "cfn_guard_output/${file}_${ruleset}.txt" + + done < <(find ./SAMtemplates -name '*.y*ml' -print0) +done + +rm -rf /tmp/ruleset