mirror of
https://github.com/prowler-cloud/prowler.git
synced 2025-12-19 05:17:47 +00:00
chore(contrib): CloudFormation of CodeBuild for v3 (#1764)
Co-authored-by: sergargar <sergio@verica.io> Co-authored-by: Toni de la Fuente <toni@blyx.com>
This commit is contained in:
398
contrib/codebuild/codebuild-prowlerv3-audit-account-cfn.yaml
Normal file
398
contrib/codebuild/codebuild-prowlerv3-audit-account-cfn.yaml
Normal file
@@ -0,0 +1,398 @@
|
||||
---
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: Creates a CodeBuild project to audit an AWS account with Prowler Version 2 and stores the html report in a S3 bucket. This will run onece at the beginning and on a schedule afterwards. Partial contribution from https://github.com/stevecjones
|
||||
Parameters:
|
||||
ServiceName:
|
||||
Description: 'Specifies the service name used within component naming'
|
||||
Type: String
|
||||
Default: 'prowler'
|
||||
|
||||
LogsRetentionInDays:
|
||||
Description: 'Specifies the number of days you want to retain CodeBuild run log events in the specified log group. Junit reports are kept for 30 days, HTML reports in S3 are not deleted'
|
||||
Type: Number
|
||||
Default: 3
|
||||
AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 180, 365]
|
||||
|
||||
ProwlerOptions:
|
||||
Description: 'Options to pass to Prowler command, use -f to filter specific regions, -c for specific checks, -s for specific services, for SecurityHub integration use "-f shub_region -S", for more options see -h. For a complete assessment leave this empty.'
|
||||
Type: String
|
||||
# Prowler command below runs a set of checks, configure it base on your needs, no options will run all regions all checks.
|
||||
Default: -f eu-west-1 -s s3 iam ec2
|
||||
|
||||
ProwlerScheduler:
|
||||
Description: The time when Prowler will run in cron format. Default is daily at 22:00h or 10PM 'cron(0 22 * * ? *)', for every 5 hours also works 'rate(5 hours)'. More info here https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html.
|
||||
Type: String
|
||||
Default: 'cron(0 22 * * ? *)'
|
||||
|
||||
Resources:
|
||||
CodeBuildStartBuild:
|
||||
Type: 'Custom::CodeBuildStartBuild'
|
||||
DependsOn:
|
||||
- CodeBuildLogPolicy
|
||||
- CodeBuildStartLogPolicy
|
||||
Properties:
|
||||
Build: !Ref ProwlerCodeBuild
|
||||
ServiceToken: !GetAtt CodeBuildStartBuildLambda.Arn
|
||||
|
||||
CodeBuildStartBuildLambdaRole:
|
||||
Type: 'AWS::IAM::Role'
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: !Sub lambda.${AWS::URLSuffix}
|
||||
Action: 'sts:AssumeRole'
|
||||
Description: !Sub 'DO NOT DELETE - Used by Lambda. Created by CloudFormation Stack ${AWS::StackId}'
|
||||
Policies:
|
||||
- PolicyName: StartBuildInline
|
||||
PolicyDocument:
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action: 'codebuild:StartBuild'
|
||||
Resource: !GetAtt ProwlerCodeBuild.Arn
|
||||
|
||||
CodeBuildStartBuildLambda:
|
||||
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:
|
||||
Handler: index.lambda_handler
|
||||
MemorySize: 128
|
||||
Role: !Sub ${CodeBuildStartBuildLambdaRole.Arn}
|
||||
Timeout: 120
|
||||
Runtime: python3.9
|
||||
Code:
|
||||
ZipFile: |
|
||||
import boto3
|
||||
import cfnresponse
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
def lambda_handler(event,context):
|
||||
props = event['ResourceProperties']
|
||||
codebuild_client = boto3.client('codebuild')
|
||||
|
||||
if (event['RequestType'] == 'Create' or event['RequestType'] == 'Update'):
|
||||
try:
|
||||
response = codebuild_client.start_build(projectName=props['Build'])
|
||||
print(response)
|
||||
print("Respond: SUCCESS")
|
||||
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
|
||||
except Exception as ex:
|
||||
print(ex.response['Error']['Message'])
|
||||
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:
|
||||
Type: AWS::S3::Bucket
|
||||
Metadata:
|
||||
cfn_nag:
|
||||
rules_to_suppress:
|
||||
- id: W35
|
||||
reason: 'S3 Access Logging is not needed'
|
||||
Properties:
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: !Sub '${ServiceName}-${AWS::AccountId}-S3-Prowler-${AWS::StackName}'
|
||||
BucketName: !Sub '${ServiceName}-reports-${AWS::Region}-prowler-${AWS::AccountId}'
|
||||
AccessControl: LogDeliveryWrite
|
||||
VersioningConfiguration:
|
||||
Status: Enabled
|
||||
BucketEncryption:
|
||||
ServerSideEncryptionConfiguration:
|
||||
- ServerSideEncryptionByDefault:
|
||||
SSEAlgorithm: AES256
|
||||
PublicAccessBlockConfiguration:
|
||||
BlockPublicAcls: true
|
||||
BlockPublicPolicy: true
|
||||
IgnorePublicAcls: true
|
||||
RestrictPublicBuckets: true
|
||||
|
||||
ArtifactBucketPolicy:
|
||||
Type: AWS::S3::BucketPolicy
|
||||
Properties:
|
||||
Bucket: !Ref ArtifactBucket
|
||||
PolicyDocument:
|
||||
Id: Content
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action: '*'
|
||||
Condition:
|
||||
Bool:
|
||||
aws:SecureTransport: false
|
||||
Effect: Deny
|
||||
Principal: '*'
|
||||
Resource: !Sub '${ArtifactBucket.Arn}/*'
|
||||
Sid: S3ForceSSL
|
||||
- Action: 's3:PutObject'
|
||||
Condition:
|
||||
'Null':
|
||||
s3:x-amz-server-side-encryption: true
|
||||
Effect: Deny
|
||||
Principal: '*'
|
||||
Resource: !Sub '${ArtifactBucket.Arn}/*'
|
||||
Sid: DenyUnEncryptedObjectUploads
|
||||
|
||||
CodeBuildServiceRole:
|
||||
Type: AWS::IAM::Role
|
||||
Metadata:
|
||||
cfn_nag:
|
||||
rules_to_suppress:
|
||||
- id: W11
|
||||
reason: 'Role complies with the least privilege principle.'
|
||||
Properties:
|
||||
Description: !Sub 'DO NOT DELETE - Used by CodeBuild. Created by CloudFormation Stack ${AWS::StackId}'
|
||||
ManagedPolicyArns:
|
||||
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/job-function/SupportUser'
|
||||
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/job-function/ViewOnlyAccess'
|
||||
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/SecurityAudit'
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action: 'sts:AssumeRole'
|
||||
Effect: Allow
|
||||
Principal:
|
||||
Service: !Sub codebuild.${AWS::URLSuffix}
|
||||
Policies:
|
||||
- PolicyName: S3
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action:
|
||||
- s3:PutObject
|
||||
- s3:GetObject
|
||||
- s3:GetObjectVersion
|
||||
- s3:GetBucketAcl
|
||||
- s3:GetBucketLocation
|
||||
Effect: Allow
|
||||
Resource: !Sub '${ArtifactBucket.Arn}/*'
|
||||
- PolicyName: ProwlerAdditions
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action:
|
||||
- account:Get*
|
||||
- appstream:Describe*
|
||||
- codeartifact:List*
|
||||
- codebuild:BatchGet*
|
||||
- ds:Get*
|
||||
- ds:Describe*
|
||||
- ds:List*
|
||||
- ec2:GetEbsEncryptionByDefault
|
||||
- ecr:Describe*
|
||||
- elasticfilesystem:DescribeBackupPolicy
|
||||
- glue:GetConnections
|
||||
- glue:GetSecurityConfiguration*
|
||||
- glue:SearchTables
|
||||
- lambda:GetFunction*
|
||||
- macie2:GetMacieSession
|
||||
- s3:GetAccountPublicAccessBlock
|
||||
- s3:GetPublicAccessBlock
|
||||
- shield:DescribeProtection
|
||||
- shield:GetSubscriptionState
|
||||
- securityhub:BatchImportFindings
|
||||
- securityhub:GetFindings
|
||||
- ssm:GetDocument
|
||||
- support:Describe*
|
||||
- tag:GetTagKeys
|
||||
Effect: Allow
|
||||
Resource: '*'
|
||||
- PolicyName: ProwlerAdditionsApiGW
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action:
|
||||
- apigateway:GET
|
||||
Effect: Allow
|
||||
Resource: 'arn:aws:apigateway:*::/restapis/*'
|
||||
- PolicyName: CodeBuild
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action:
|
||||
- codebuild:CreateReportGroup
|
||||
- codebuild:CreateReport
|
||||
- codebuild:UpdateReport
|
||||
- codebuild:BatchPutTestCases
|
||||
- codebuild:BatchPutCodeCoverages
|
||||
Effect: Allow
|
||||
Resource: !Sub 'arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/*'
|
||||
- PolicyName: SecurityHubBatchImportFindings
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action: securityhub:BatchImportFindings
|
||||
Effect: Allow
|
||||
Resource: !Sub 'arn:${AWS::Partition}:securityhub:${AWS::Region}::product/prowler/prowler'
|
||||
|
||||
CodeBuildLogPolicy:
|
||||
Type: AWS::IAM::Policy
|
||||
Properties:
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Action:
|
||||
- logs:CreateLogStream
|
||||
- logs:PutLogEvents
|
||||
Effect: Allow
|
||||
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:
|
||||
Type: AWS::CodeBuild::Project
|
||||
Metadata:
|
||||
cfn_nag:
|
||||
rules_to_suppress:
|
||||
- id: W32
|
||||
reason: 'KMS encryption is not needed.'
|
||||
Properties:
|
||||
Artifacts:
|
||||
Type: NO_ARTIFACTS
|
||||
ConcurrentBuildLimit: 1
|
||||
Source:
|
||||
Type: NO_SOURCE
|
||||
BuildSpec: |
|
||||
version: 0.2
|
||||
phases:
|
||||
install:
|
||||
runtime-versions:
|
||||
python: 3.9
|
||||
commands:
|
||||
- echo "Installing Prowler..."
|
||||
- pip3 install prowler
|
||||
build:
|
||||
commands:
|
||||
- echo "Running Prowler as prowler $PROWLER_OPTIONS"
|
||||
- prowler $PROWLER_OPTIONS
|
||||
post_build:
|
||||
commands:
|
||||
- echo "Uploading reports to S3..."
|
||||
- aws s3 cp --sse AES256 output/ s3://$BUCKET_REPORT/ --recursive
|
||||
- echo "Done!"
|
||||
# Currently not supported in Version 3
|
||||
# reports:
|
||||
# prowler:
|
||||
# files:
|
||||
# - '**/*'
|
||||
# base-directory: 'junit-reports'
|
||||
# file-format: JunitXml
|
||||
Environment:
|
||||
# AWS CodeBuild free tier includes 100 build minutes of BUILD_GENERAL1_SMALL per month.
|
||||
# BUILD_GENERAL1_SMALL: Use up to 3 GB memory and 2 vCPUs for builds. $0.005/minute.
|
||||
# BUILD_GENERAL1_MEDIUM: Use up to 7 GB memory and 4 vCPUs for builds. $0.01/minute.
|
||||
# BUILD_GENERAL1_LARGE: Use up to 15 GB memory and 8 vCPUs for builds. $0.02/minute.
|
||||
# BUILD_GENERAL1_2XLARGE: Use up to 144 GB memory and 72 vCPUs for builds. $0.20/minute.
|
||||
ComputeType: "BUILD_GENERAL1_SMALL"
|
||||
Image: "aws/codebuild/amazonlinux2-x86_64-standard:3.0"
|
||||
Type: "LINUX_CONTAINER"
|
||||
EnvironmentVariables:
|
||||
- Name: BUCKET_REPORT
|
||||
Value: !Ref ArtifactBucket
|
||||
Type: PLAINTEXT
|
||||
- Name: PROWLER_OPTIONS
|
||||
Value: !Ref ProwlerOptions
|
||||
Type: PLAINTEXT
|
||||
Description: Run Prowler assessment
|
||||
ServiceRole: !GetAtt CodeBuildServiceRole.Arn
|
||||
TimeoutInMinutes: 300
|
||||
|
||||
ProwlerLogGroup:
|
||||
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/codebuild/${ProwlerCodeBuild}'
|
||||
RetentionInDays: !Ref LogsRetentionInDays
|
||||
|
||||
EventBridgeServiceRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
Description: !Sub 'DO NOT DELETE - Used by EventBridge. Created by CloudFormation Stack ${AWS::StackId}'
|
||||
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
|
||||
State: ENABLED
|
||||
Targets:
|
||||
- Arn: !GetAtt ProwlerCodeBuild.Arn
|
||||
Id: ProwlerSchedule
|
||||
RoleArn: !GetAtt EventBridgeServiceRole.Arn
|
||||
|
||||
Outputs:
|
||||
ArtifactBucketName:
|
||||
Description: Artifact Bucket Name
|
||||
Value: !Ref ArtifactBucket
|
||||
Reference in New Issue
Block a user