Update CloudFormation template for CodeBuild (#1114)

This commit is contained in:
Justin Plock
2022-05-03 03:14:38 -04:00
committed by GitHub
parent 681d0d9538
commit 04e5804665

View File

@@ -28,12 +28,12 @@ Parameters:
Resources: Resources:
CodeBuildStartBuild: CodeBuildStartBuild:
Type: 'Custom::CodeBuildStartBuild' Type: 'Custom::CodeBuildStartBuild'
DependsOn:
- CodeBuildLogPolicy
- CodeBuildStartLogPolicy
Properties: Properties:
Build: !Ref ProwlerCodeBuild Build: !Ref ProwlerCodeBuild
ServiceToken: ServiceToken: !GetAtt CodeBuildStartBuildLambda.Arn
'Fn::GetAtt':
- CodeBuildStartBuildLambda
- Arn
CodeBuildStartBuildLambdaRole: CodeBuildStartBuildLambdaRole:
Type: 'AWS::IAM::Role' Type: 'AWS::IAM::Role'
@@ -43,29 +43,34 @@ Resources:
Statement: Statement:
- Effect: Allow - Effect: Allow
Principal: Principal:
Service: lambda.amazonaws.com Service: !Sub lambda.${AWS::URLSuffix}
Action: Action: 'sts:AssumeRole'
- 'sts:AssumeRole' Description: !Sub 'DO NOT DELETE - Used by Lambda. Created by CloudFormation Stack ${AWS::StackId}'
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Policies: Policies:
- PolicyName: StartBuildInline - PolicyName: StartBuildInline
PolicyDocument: PolicyDocument:
Statement: Statement:
- Effect: Allow - Effect: Allow
Action: Action: 'codebuild:StartBuild'
- 'codebuild:StartBuild' Resource: !GetAtt ProwlerCodeBuild.Arn
Resource: '*'
CodeBuildStartBuildLambda: CodeBuildStartBuildLambda:
Type: 'AWS::Lambda::Function' Type: 'AWS::Lambda::Function'
Metadata:
cfn_nag:
rules_to_suppress:
- id: W58
reason: 'This Lambda has permissions to write Logs'
- id: W89
reason: 'VPC is not needed'
- id: W92
reason: 'ReservedConcurrentExecutions not needed'
Properties: Properties:
Handler: index.lambda_handler Handler: index.lambda_handler
MemorySize: 128 MemorySize: 128
Role: !Sub ${CodeBuildStartBuildLambdaRole.Arn} Role: !Sub ${CodeBuildStartBuildLambdaRole.Arn}
Timeout: 120 Timeout: 120
Runtime: python3.6 Runtime: python3.9
Code: Code:
ZipFile: | ZipFile: |
import boto3 import boto3
@@ -74,24 +79,59 @@ Resources:
def lambda_handler(event,context): def lambda_handler(event,context):
props = event['ResourceProperties'] props = event['ResourceProperties']
codebuil_client = boto3.client('codebuild') codebuild_client = boto3.client('codebuild')
if (event['RequestType'] == 'Create' or event['RequestType'] == 'Update'): if (event['RequestType'] == 'Create' or event['RequestType'] == 'Update'):
try: try:
response = codebuil_client.start_build(projectName=props['Build']) response = codebuild_client.start_build(projectName=props['Build'])
print(response) print(response)
print("Respond: SUCCESS") print("Respond: SUCCESS")
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as ex: except Exception as ex:
print(ex.response['Error']['Message']) print(ex.response['Error']['Message'])
cfnresponse.send(event, context, cfnresponse.FAILED, ex.response) cfnresponse.send(event, context, cfnresponse.FAILED, ex.response)
else:
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
CodeBuildStartLogGroup:
Type: 'AWS::Logs::LogGroup'
DeletionPolicy: Delete
UpdateReplacePolicy: Delete
Metadata:
cfn_nag:
rules_to_suppress:
- id: W84
reason: 'KMS encryption is not needed.'
Properties:
LogGroupName: !Sub '/aws/lambda/${CodeBuildStartBuildLambda}'
RetentionInDays: !Ref LogsRetentionInDays
CodeBuildStartLogPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource: !GetAtt CodeBuildStartLogGroup.Arn
PolicyName: LogGroup
Roles:
- !Ref CodeBuildStartBuildLambdaRole
ArtifactBucket: ArtifactBucket:
Type: AWS::S3::Bucket Type: AWS::S3::Bucket
Metadata:
cfn_nag:
rules_to_suppress:
- id: W35
reason: 'S3 Access Logging is not needed'
Properties: Properties:
Tags: Tags:
- Key: Name - Key: Name
Value: !Join ['-', [!Ref 'ServiceName', !Ref 'AWS::AccountId', 'S3', 'Prowler', !Ref 'AWS::StackName']] Value: !Sub '${ServiceName}-${AWS::AccountId}-S3-Prower-${AWS::StackName}'
BucketName: !Sub '${ServiceName}-reports-${AWS::Region}-prowler-${AWS::AccountId}' BucketName: !Sub '${ServiceName}-reports-${AWS::Region}-prowler-${AWS::AccountId}'
AccessControl: LogDeliveryWrite AccessControl: LogDeliveryWrite
VersioningConfiguration: VersioningConfiguration:
@@ -109,7 +149,7 @@ Resources:
ArtifactBucketPolicy: ArtifactBucketPolicy:
Type: AWS::S3::BucketPolicy Type: AWS::S3::BucketPolicy
Properties: Properties:
Bucket: !Ref 'ArtifactBucket' Bucket: !Ref ArtifactBucket
PolicyDocument: PolicyDocument:
Id: Content Id: Content
Version: '2012-10-17' Version: '2012-10-17'
@@ -117,20 +157,18 @@ Resources:
- Action: '*' - Action: '*'
Condition: Condition:
Bool: Bool:
aws:SecureTransport: 'false' aws:SecureTransport: false
Effect: Deny Effect: Deny
Principal: '*' Principal: '*'
Resource: Resource: !Sub '${ArtifactBucket.Arn}/*'
- !Join ['', ['arn:aws:s3:::', !Ref 'ArtifactBucket', '/*']]
Sid: S3ForceSSL Sid: S3ForceSSL
- Action: 's3:PutObject' - Action: 's3:PutObject'
Condition: Condition:
'Null': 'Null':
s3:x-amz-server-side-encryption: 'true' s3:x-amz-server-side-encryption: true
Effect: Deny Effect: Deny
Principal: '*' Principal: '*'
Resource: Resource: !Sub '${ArtifactBucket.Arn}/*'
- !Join ['', ['arn:aws:s3:::', !Ref 'ArtifactBucket', '/*']]
Sid: DenyUnEncryptedObjectUploads Sid: DenyUnEncryptedObjectUploads
CodeBuildServiceRole: CodeBuildServiceRole:
@@ -138,35 +176,22 @@ Resources:
Metadata: Metadata:
cfn_nag: cfn_nag:
rules_to_suppress: rules_to_suppress:
- id: W28 - id: W11
reason: "Explicit name is required for this resource to avoid circular dependencies." reason: 'Role complies with the least privilege principle.'
Properties: Properties:
RoleName: 'prowler-codebuild-role' Description: !Sub 'DO NOT DELETE - Used by CodeBuild. Created by CloudFormation Stack ${AWS::StackId}'
Path: '/service-role/'
ManagedPolicyArns: ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/job-function/SupportUser' - !Sub 'arn:${AWS::Partition}:iam::aws:policy/job-function/SupportUser'
- 'arn:aws:iam::aws:policy/job-function/ViewOnlyAccess' - !Sub 'arn:${AWS::Partition}:iam::aws:policy/job-function/ViewOnlyAccess'
- 'arn:aws:iam::aws:policy/SecurityAudit' - !Sub 'arn:${AWS::Partition}:iam::aws:policy/SecurityAudit'
AssumeRolePolicyDocument: AssumeRolePolicyDocument:
Version: '2012-10-17' Version: '2012-10-17'
Statement: Statement:
- - Action: 'sts:AssumeRole'
Action: 'sts:AssumeRole'
Effect: Allow Effect: Allow
Principal: Principal:
Service: Service: !Sub codebuild.${AWS::URLSuffix}
- codebuild.amazonaws.com
Policies: Policies:
- PolicyName: LogGroup
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*'
- PolicyName: S3 - PolicyName: S3
PolicyDocument: PolicyDocument:
Version: '2012-10-17' Version: '2012-10-17'
@@ -178,7 +203,7 @@ Resources:
- s3:GetBucketAcl - s3:GetBucketAcl
- s3:GetBucketLocation - s3:GetBucketLocation
Effect: Allow Effect: Allow
Resource: !Sub 'arn:aws:s3:::${ArtifactBucket}/*' Resource: !Sub '${ArtifactBucket.Arn}/*'
- PolicyName: ProwlerAdditions - PolicyName: ProwlerAdditions
PolicyDocument: PolicyDocument:
Version: '2012-10-17' Version: '2012-10-17'
@@ -211,49 +236,71 @@ Resources:
- codebuild:BatchPutTestCases - codebuild:BatchPutTestCases
- codebuild:BatchPutCodeCoverages - codebuild:BatchPutCodeCoverages
Effect: Allow Effect: Allow
Resource: !Sub 'arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*' Resource: !Sub 'arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*'
- PolicyName: SecurityHubBatchImportFindings - PolicyName: SecurityHubBatchImportFindings
PolicyDocument: PolicyDocument:
Version: '2012-10-17' Version: '2012-10-17'
Statement: Statement:
- Action: - Action: securityhub:BatchImportFindings
- securityhub:BatchImportFindings
Effect: Allow Effect: Allow
Resource: !Sub 'arn:aws:securityhub:${AWS::Region}::product/prowler/prowler' Resource: !Sub 'arn:${AWS::Partition}:securityhub:${AWS::Region}::product/prowler/prowler'
- PolicyName: AssumeRole
CodeBuildLogPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument: PolicyDocument:
Version: '2012-10-17' Version: '2012-10-17'
Statement: Statement:
- Action: - Action:
- sts:AssumeRole - logs:CreateLogStream
- logs:PutLogEvents
Effect: Allow Effect: Allow
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:role/service-role/prowler-codebuild-role' Resource: !GetAtt ProwlerLogGroup.Arn
PolicyName: LogGroup
Roles:
- !Ref CodeBuildServiceRole
CodeBuildAssumePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action: 'sts:AssumeRole'
Effect: Allow
Resource: !GetAtt CodeBuildServiceRole.Arn
PolicyName: AssumeRole
Roles:
- !Ref CodeBuildServiceRole
ProwlerCodeBuild: ProwlerCodeBuild:
Type: AWS::CodeBuild::Project Type: AWS::CodeBuild::Project
Metadata:
cfn_nag:
rules_to_suppress:
- id: W32
reason: 'KMS encryption is not needed.'
Properties: Properties:
Artifacts: Artifacts:
Type: NO_ARTIFACTS Type: NO_ARTIFACTS
ConcurrentBuildLimit: 1
Source: Source:
Type: NO_SOURCE GitCloneDepth: 1
Location: https://github.com/prowler-cloud/prowler
Type: GITHUB
ReportBuildStatus: false
BuildSpec: | BuildSpec: |
version: 0.2 version: 0.2
phases: phases:
install: install:
runtime-versions: runtime-versions:
python: 3.8 python: 3.9
commands: commands:
- echo "Installing Prowler and dependencies..." - echo "Installing Prowler and dependencies..."
- pip3 install detect-secrets - pip3 install detect-secrets
- yum -y install jq
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
- unzip awscliv2.zip
- ./aws/install
- git clone https://github.com/prowler-cloud/prowler
build: build:
commands: commands:
- echo "Running Prowler as ./prowler $PROWLER_OPTIONS" - echo "Running Prowler as ./prowler $PROWLER_OPTIONS"
- cd prowler
- ./prowler $PROWLER_OPTIONS - ./prowler $PROWLER_OPTIONS
post_build: post_build:
commands: commands:
@@ -264,7 +311,7 @@ Resources:
prowler: prowler:
files: files:
- '**/*' - '**/*'
base-directory: 'prowler/junit-reports' base-directory: 'junit-reports'
file-format: JunitXml file-format: JunitXml
Environment: Environment:
# AWS CodeBuild free tier includes 100 build minutes of BUILD_GENERAL1_SMALL per month. # AWS CodeBuild free tier includes 100 build minutes of BUILD_GENERAL1_SMALL per month.
@@ -277,73 +324,60 @@ Resources:
Type: "LINUX_CONTAINER" Type: "LINUX_CONTAINER"
EnvironmentVariables: EnvironmentVariables:
- Name: BUCKET_REPORT - Name: BUCKET_REPORT
Value: !Ref 'ArtifactBucket' Value: !Ref ArtifactBucket
Type: PLAINTEXT Type: PLAINTEXT
- Name: PROWLER_OPTIONS - Name: PROWLER_OPTIONS
Value: !Ref 'ProwlerOptions' Value: !Ref ProwlerOptions
Type: PLAINTEXT Type: PLAINTEXT
Description: Run Prowler assessment Description: Run Prowler assessment
ServiceRole: !GetAtt CodeBuildServiceRole.Arn ServiceRole: !GetAtt CodeBuildServiceRole.Arn
TimeoutInMinutes: 300 TimeoutInMinutes: 300
ProwlerCodeBuildReportGroup:
Type: AWS::CodeBuild::ReportGroup
Properties:
Name: !Sub 'prowler-report-group-${ServiceName}-${AWS::StackName}'
Type: TEST
ExportConfig:
ExportConfigType: NO_EXPORT
ProwlerLogGroup: ProwlerLogGroup:
Type: 'AWS::Logs::LogGroup' Type: 'AWS::Logs::LogGroup'
DeletionPolicy: Delete
UpdateReplacePolicy: Delete
Metadata:
cfn_nag:
rules_to_suppress:
- id: W84
reason: 'KMS encryption is not needed.'
Properties: Properties:
LogGroupName: !Sub '/aws/codebuild/${ProwlerCodeBuild}' LogGroupName: !Sub '/aws/codebuild/${ProwlerCodeBuild}'
RetentionInDays: !Ref LogsRetentionInDays RetentionInDays: !Ref LogsRetentionInDays
ProwlerSchedule: EventBridgeServiceRole:
Type: "AWS::Events::Rule" Type: AWS::IAM::Role
Properties: Properties:
Description: > Description: !Sub 'DO NOT DELETE - Used by EventBridge. Created by CloudFormation Stack ${AWS::StackId}'
A schedule for the Lambda function that triggers Prowler in CodeBuild.. AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Action: 'sts:AssumeRole'
Effect: Allow
Principal:
Service: !Sub events.${AWS::URLSuffix}
Policies:
- PolicyName: CodeBuild
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'codebuild:StartBuild'
Resource: !GetAtt ProwlerCodeBuild.Arn
ProwlerSchedule:
Type: 'AWS::Events::Rule'
Properties:
Description: A schedule to trigger Prowler in CodeBuild
ScheduleExpression: !Ref ProwlerScheduler ScheduleExpression: !Ref ProwlerScheduler
State: ENABLED State: ENABLED
Targets: Targets:
- Arn: !Sub ${ProwlerScheduleLambdaFunction.Arn} - Arn: !GetAtt ProwlerCodeBuild.Arn
Id: ProwlerSchedule Id: ProwlerSchedule
RoleArn: !GetAtt EventBridgeServiceRole.Arn
ProwlerSchedulePermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !Sub ${ProwlerScheduleLambdaFunction.Arn}
Principal: 'events.amazonaws.com'
SourceArn: !Sub ${ProwlerSchedule.Arn}
ProwlerScheduleLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler: index.lambda_handler
MemorySize: 128
Role: !Sub ${CodeBuildStartBuildLambdaRole.Arn}
Timeout: 120
Runtime: python3.6
Environment:
Variables:
buildName: !Ref ProwlerCodeBuild
Code:
ZipFile: |
import boto3
import os
def lambda_handler(event,context):
codebuild_client = boto3.client('codebuild')
print("Running Prowler scheduled!: " + os.environ['buildName'])
project_name = os.environ['buildName']
response = codebuild_client.start_build(projectName=project_name)
print(response)
print("Respond: SUCCESS")
Outputs: Outputs:
ArtifactBucketName: ArtifactBucketName:
Description: Artifact Bucket Name Description: Artifact Bucket Name
Value: !Ref 'ArtifactBucket' Value: !Ref ArtifactBucket