--- AWSTemplateFormatVersion: '2010-09-09' Description: Prowler Auditing Tools Stack Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "Organizations and Accounts" Parameters: - pOrgMasterAccounts - pOrgExcludedAccounts - pStandAloneAccounts - Label: default: "Check Group and Execution" Parameters: - pProwlerCheckGroup - pAuditEveryXHours - Label: default: "Advanced" Parameters: - pTimeoutMinutes - pAuditRolePathName - pCustomProwlerRepo - pCustomProwlerCloneArgs ParameterLabels: pOrgMasterAccounts: default: "Organization Master Accounts" pOrgExcludedAccounts: default: "Excluded Organiztion Members" pStandAloneAccounts: default: "Stand-alone Accounts" pProwlerCheckGroup: default: "Prowler Check Group" pAuditEveryXHours: default: "Perform Audit every X hours" pTimeoutMinutes: default: "Permit Audit to run for X minutes" pAuditRolePathName: default: "Custom audit role path" pCustomProwlerRepo: default: "Custom git repo location for prowler" pCustomProwlerCloneArgs: default: "Custom arguments to git clone --depth 1" Parameters: pAuditEveryXHours: Default: 24 Type: Number Description: Number of hours between prowler audit runs. MinValue: 2 MaxValue: 168 pTimeoutMinutes: Default: 30 Type: Number Description: Timeout for running prowler across the fleet MinValue: 5 MaxValue: 480 pAuditRolePathName: Default: '/audit/prowler/XA_AuditRole_Prowler' Type: String Description: Role path and name which prowler will assume in the target accounts (Audit_Exec_Role.yaml) # TODO: Validation: begins with "/" and does NOT end with "/" pOrgMasterAccounts: Description: Comma Separated list of Organization Master Accounts, or 'none' Default: 'none' Type: String MinLength: 4 AllowedPattern: ^(none|([0-9]{12}(,[0-9]{12})*))$ ConstraintDescription: comma separated list 12-digit account numbers, or 'none' pOrgExcludedAccounts: # Comma Separated list of Org Member Accounts to EXCLUDE Description: Comma Separated list of Skipped Organization Member Accounts, or 'none' Default: 'none' Type: String MinLength: 4 AllowedPattern: ^(none|([0-9]{12}(,[0-9]{12})*))$ ConstraintDescription: comma separated list 12-digit account numbers, or 'none' pStandAloneAccounts: # Comma Separated list of Stand-Alone Accounts Description: Comma Separated list of Stand-alone Accounts, or 'none' Default: 'none' Type: String MinLength: 4 AllowedPattern: ^(none|([0-9]{12}(,[0-9]{12})*))$ ConstraintDescription: comma separated list 12-digit account numbers, or 'none' pProwlerCheckGroup: Default: 'cislevel1' Type: String Description: Which group of checks should prowler run AllowedValues: - 'group1' - 'group2' - 'group3' - 'group4' - 'cislevel1' - 'cislevel2' - 'extras' - 'forensics-ready' - 'gdpr' - 'hipaa' - 'secrets' - 'apigateway' - 'rds' pCustomProwlerRepo: Type: String Default: 'https://github.com/prowler-cloud/prowler.git' MinLength: 10 pCustomProwlerCloneArgs: Type: String Default: '--branch master' MinLength: 0 ##### TODO # pResultsBucket: # if specified, use an existing bucket for the data # pEnableAthena: # Default: false # Type: Boolean # Description: Set to true to enable creation of Athena/QuickSight resources #### TODO # Conditions: # cUseAthena: False Resources: # S3 Bucket for Results, Config ProwlerResults: Type: "AWS::S3::Bucket" Properties: # BucketName: !Sub "audit-results-${AWS::AccountId}" Tags: - Key: "data-type" Value: "it-audit:sensitive" - Key: "data-public" Value: "NO" AccessControl: Private BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True # LoggingConfiguration: # TODO: Enable BucketLogging - requires more parameters DeletionPolicy: "Retain" Metadata: cfn_nag: rules_to_suppress: - id: W35 reason: "Bucket logging requires additional configuration not yet supported by this template" # Policy to allow assuming the XA_AuditRole_Prowler in target accounts ProwlerAuditManagerRole: Type: AWS::IAM::Role Properties: RoleName: AuditManagerRole_Prowler AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: codebuild.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: AssumeRole-XA_AuditRole_Prowler PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - sts:AssumeRole Resource: - !Sub "arn:aws:iam::*:role${pAuditRolePathName}" - Effect: Allow Action: - s3:PutObject - s3:GetObject - s3:GetObjectVersion Resource: - !Sub "${ProwlerResults.Arn}/*" - Effect: Allow Action: - s3:ListBucket - s3:HeadBucket - s3:GetBucketLocation - s3:GetBucketAcl Resource: - !Sub "${ProwlerResults.Arn}" - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:*" - !Sub "${ProwlerResults.Arn}" - Effect: Allow Action: - ssm:GetParameters Resource: - !Sub "arn:aws:ssm:us-east-1:${AWS::AccountId}:parameter/audit/prowler/config/*" Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "the role name is intentionally static" - id: W11 reason: "not sure where the violation of w11 is" ## Code Build Job ProwlerBuildProject: Type: "AWS::CodeBuild::Project" Properties: Name: PerformProwlerAudit Description: "Run Prowler audit on accounts in targeted organizations" QueuedTimeoutInMinutes: 480 TimeoutInMinutes: !Ref pTimeoutMinutes ServiceRole: !Ref ProwlerAuditManagerRole EncryptionKey: !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:alias/aws/s3" Environment: Type: "LINUX_CONTAINER" ComputeType: "BUILD_GENERAL1_MEDIUM" PrivilegedMode: False Image: "aws/codebuild/standard:2.0-1.12.0" ImagePullCredentialsType: "CODEBUILD" Artifacts: # s3://stack-prowlerresults-randomness/prowler/results/... Name: "results" Type: "S3" Location: !Ref ProwlerResults Path: "prowler" NamespaceType: NONE Packaging: NONE OverrideArtifactName: False EncryptionDisabled: False LogsConfig: # S3/logs/pipeline/ CloudWatchLogs: Status: ENABLED GroupName: "audit/prowler" StreamName: "codebuild_runs" S3Logs: Status: DISABLED # Location: !Sub "${ProwlerResults.Arn}/codebuild_run_logs" EncryptionDisabled: False BadgeEnabled: False Tags: - Key: "data-type" Value: "it-audit:sensitive" - Key: "data-public" Value: "NO" Cache: Type: "NO_CACHE" Source: Type: NO_SOURCE BuildSpec: | version: 0.2 env: parameter-store: PROWL_CHECK_GROUP: /audit/prowler/config/check_group PROWL_MASTER_ACCOUNTS: /audit/prowler/config/orgmaster_accounts PROWL_STANDALONE_ACCOUNTS: /audit/prowler/config/standalone_accounts PROWL_SKIP_ACCOUNTS: /audit/prowler/config/skip_accounts PROWL_AUDIT_ROLE: /audit/prowler/config/audit_role PROWLER_REPO: /audit/prowler/config/gitrepo PROWLER_CLONE_ARGS: /audit/prowler/config/gitcloneargs phases: install: runtime-versions: python: 3.7 commands: - aws --version - git clone --depth 1 $PROWLER_REPO $PROWLER_CLONE_ARGS pre_build: commands: - env | grep PROWL_ - export OUTBASE=$(date -u +"out/diagnostics/%Y/%m/%d") - export STAMP=$(date -u +"%Y%m%dT%H%M%SZ") - mkdir -p $OUTBASE || true - prowler/prowler -V - aws sts get-caller-identity > ${OUTBASE}/${STAMP}-caller-id.json build: commands: #### Run Prowler against this account, but don't fail the build # - export PROWLER_ACCOUNT_ID=$(aws sts get-caller-identity | jq -r '.Account') # - /bin/bash prowler/prowler -g cislevel1 -M csv -n -k > ${OUTBASE}/${STAMP}.${PROWLER_ACCOUNT_ID}.prowler.cislevel1.csv || /bin/true # - /bin/bash prowler/prowler -g forensics-ready -M csv -n -k > ${OUTBASE}/${STAMP}.${PROWLER_ACCOUNT_ID}.prowler.forensics-ready.csv || /bin/true #### Run Prowler targeting all accounts in the configured organizations - test -f prowler/util/multi-account/config - /bin/bash prowler/util/multi-account/megaprowler.sh out finally: - ps axuwww | grep -E 'parallel|sem|prowler' post_build: commands: - echo "attempting to collect any prowler credential reports ..." - find /tmp/ -name prowler\* | xargs -I % cp % ${OUTDIAG} || true artifacts: files: - '**/*' discard-paths: no base-directory: out ProwlerAuditTriggerRole: Type: AWS::IAM::Role Properties: # RoleName: Let cloudformation create this AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: AssumeRole-XA_AuditRole_Prowler PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - codebuild:StartBuild Resource: - !GetAtt ProwlerBuildProject.Arn ProwlerAuditTrigger: Type: AWS::Events::Rule Properties: Description: !Sub "Execute Prowler audit every ${pAuditEveryXHours} hours" Name: "ScheduledProwler" RoleArn: !GetAtt ProwlerAuditTriggerRole.Arn ## Other ways to define scheduling # ScheduleExpression: "cron(MM HH ? * * *)" # ScheduleExpression: "cron(45 15 ? * * *)" # ScheduleExpression: !Sub "rate( ${pAuditEveryXHours} hours)" ScheduleExpression: !Sub "rate(${pAuditEveryXHours} hours)" State: ENABLED Targets: - Arn: !GetAtt ProwlerBuildProject.Arn Id: 'ScheduledProwler' RoleArn: !GetAtt ProwlerAuditTriggerRole.Arn ProwlerConfigCheckGroup: Type: AWS::SSM::Parameter Properties: Description: "Name of the prowler check group to use" Name: "/audit/prowler/config/check_group" Type: "String" Value: !Ref pProwlerCheckGroup ProwlerConfigMasterAccounts: Type: AWS::SSM::Parameter Properties: Description: "List of organization master accounts" Name: "/audit/prowler/config/orgmaster_accounts" Type: "String" Value: !Ref pOrgMasterAccounts ProwlerConfigStandAloneAccounts: Type: AWS::SSM::Parameter Properties: Description: "List of stand-alone accounts" Name: "/audit/prowler/config/standalone_accounts" Type: "String" Value: !Ref pStandAloneAccounts ProwlerConfigSkipAccounts: Type: AWS::SSM::Parameter Properties: Description: "List of skipped organization member accounts" Name: "/audit/prowler/config/skip_accounts" Type: "String" Value: !Ref pOrgExcludedAccounts ProwlerConfigAuditRole: Type: AWS::SSM::Parameter Properties: Description: "Role used to audit target accounts" Name: "/audit/prowler/config/audit_role" Type: "String" Value: !Ref pAuditRolePathName ProwlerConfigGitRepo: Type: AWS::SSM::Parameter Properties: Description: "Git repository where prowler is gathered" Name: "/audit/prowler/config/gitrepo" Type: "String" Value: !Ref pCustomProwlerRepo ProwlerConfigGitCloneArgs: Type: AWS::SSM::Parameter Properties: Description: "Git clone arguments" Name: "/audit/prowler/config/gitcloneargs" Type: "String" Value: !Ref pCustomProwlerCloneArgs # -- Conditional "cUseAthena" # Athena # QuickSight # ??? Outputs: ResultsBucket: Description: S3 Bucket with Prowler Results, Logs, Configs Value: !Ref ProwlerResults