Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow CN region and add lint #759

Merged
merged 3 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
matrix:
include:
- {python-version: '3.7' }
- {python-version: '3.10' }
- {python-version: '3.11' }
steps:
- name: Git clone the repository
uses: actions/checkout@v3
Expand Down Expand Up @@ -105,6 +105,31 @@ jobs:
run: |
cfn-lint ./cfn-templates/cid-admin-policies.yaml

cfn-scan-cur-aggregation:
runs-on: ubuntu-latest
steps:
- name: Git clone the repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
- name: Install CFN tools
run: |
gem install cfn-nag
- name: CFN Nag scan
run: |
cfn_nag_scan --input-path ./cfn-templates/cur-aggregation.yaml
- name: Install cfn-lint
run: |
pip install cfn-lint
- name: CFN Lint
run: |
cfn-lint ./cfn-templates/cur-aggregation.yaml

terraform-scan:
runs-on: ubuntu-latest
Expand Down
97 changes: 78 additions & 19 deletions cfn-templates/cid-cfn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ Conditions:
- !Condition NeedDataBucketsKms

Resources:
SpiceRefreshExecutionRole: #Role needed to schedule spice ingestion for the datasets
SpiceRefreshExecutionRole: #Role needed to schedule spice ingestion for the datasets not used by default
Type: AWS::IAM::Role
Condition: NeedRefreshDatasets
Properties:
Expand All @@ -290,8 +290,6 @@ Resources:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- !Sub arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: !Sub 'CidSpiceRefreshExecutionRole${Suffix}'
PolicyDocument:
Expand All @@ -309,6 +307,13 @@ Resources:
Action: quicksight:ListIngestions
Resource:
- !Sub 'arn:${AWS::Partition}:quicksight:${AWS::Region}:${AWS::AccountId}:dataset/*/ingestion/*'
ManagedPolicyArns:
- !Sub arn:${AWS::Partition}:iam:policy/service-role/AWSLambdaBasicExecutionRole
Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W28'
reason: "Need explicit name to give permissions"

# Currently QS has no api for managing updates, so we need to set up a scheduled lambda.
# Once QS will provide the API for scheduling this will be removed.
Expand Down Expand Up @@ -395,6 +400,13 @@ Resources:
IngestionId=datetime.now().strftime("%d%m%y-%H%M%S-%f"),
)
print('DEBUG: response=', res)
Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W89'
reason: "No need to access to VPC resources"
- id: 'W92'
reason: "No need for reserved concurrency"

SpiceRefreshRule:
Type: AWS::Events::Rule
Expand Down Expand Up @@ -442,6 +454,12 @@ Resources:
config:
ignore_checks:
- W3045 #Consider using AWS::S3::BucketPolicy instead of AccessControl; standard Athena results setup
cfn_nag:
rules_to_suppress:
- id: 'W35'
reason: "Data buckets would generate too much logs"
- id: 'W51'
reason: "No policy needed"

MyAthenaWorkGroup:
Type: AWS::Athena::WorkGroup
Expand Down Expand Up @@ -487,6 +505,13 @@ Resources:
print(f"Status code: {response}")
except Exception as exc:
print("Failed sending PUT to CFN: " + str(exc))
Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W89'
reason: "No need to access to VPC resources"
- id: 'W92'
reason: "No need for reserved concurrency"

CustomResourceFunctionInit:
Type: AWS::Lambda::Function
Expand Down Expand Up @@ -614,6 +639,13 @@ Resources:
WORKGROUP: !If [NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, '']
CRAWLER: !If [NeedCURTable, !Ref MyGlueCURCrawler, '']
QUICKSIGHT_USER: !Ref QuickSightUser
Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W89'
reason: "No need to access to VPC resources"
- id: 'W92'
reason: "No need for reserved concurrency"

InitLambdaExecutionRole:
Type: AWS::IAM::Role
Expand All @@ -637,7 +669,7 @@ Resources:
Action: quicksight:DescribeUser
Resource: !Sub 'arn:${AWS::Partition}:quicksight:*:${AWS::AccountId}:user/default/${QuickSightUser}' # region=* as at this moment we do not know the Identity region where QS stores users
ManagedPolicyArns:
- !Sub arn:${AWS::Partition}:iam::aws:policy/AWSLambdaExecute
- !Sub arn:${AWS::Partition}:iam:policy/service-role/AWSLambdaBasicExecutionRole

InitLambdaExecutionRoleWorkGroupPolicy:
Type: AWS::IAM::Policy
Expand Down Expand Up @@ -724,7 +756,7 @@ Resources:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- !Sub arn:${AWS::Partition}:iam::aws:policy/AWSLambdaExecute
- !Sub arn:${AWS::Partition}:iam:policy/service-role/AWSLambdaBasicExecutionRole
CustomResourceProcessPath:
Type: AWS::Lambda::Function
Properties:
Expand Down Expand Up @@ -813,6 +845,13 @@ Resources:
if e.response['Error']['Code'] == '404':
return False
return True
Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W89'
reason: "No need to access to VPC resources"
- id: 'W92'
reason: "No need for reserved concurrency"

CURPath:
Type: Custom::CustomResourceProcessPath
Expand Down Expand Up @@ -1120,7 +1159,13 @@ Resources:
- NeedAthenaQueryResultsBucket
- !Sub 'arn:${AWS::Partition}:s3:::${MyAthenaQueryResultsBucket}/*'
- !Sub 'arn:${AWS::Partition}:s3:::${AthenaQueryResultsBucket}/*'

Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W11'
reason: "Need to use * for Lakeformation and Athena"
- id: 'W28'
reason: "Need explicit name to give permissions"
QuickSightDataSourceRolePolicyForODCBucket:
Type: AWS::IAM::Policy
Condition: NeedQuickSightDataSourceRole # We need ODC bucket even if ODC dashboards are not activated (ex: for account map)
Expand All @@ -1132,13 +1177,13 @@ Resources:
- Sid: CidAllowListBucket
Effect: Allow
Action: s3:ListBucket
Resource: !Sub arn:aws:s3:::${ODCPath.Bucket}
Resource: !Sub arn:${AWS::Partition}:s3:::${ODCPath.Bucket}
- Sid: CidAllowReadBucket
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource: !Sub arn:aws:s3:::${ODCPath.Bucket}/*
Resource: !Sub arn:${AWS::Partition}:s3:::${ODCPath.Bucket}/*
Roles:
- !Ref QuickSightDataSourceRole
QuickSightDataSourceRolePolicyForCURBucket:
Expand All @@ -1152,15 +1197,16 @@ Resources:
- Sid: CidAllowListBucket
Effect: Allow
Action: s3:ListBucket
Resource: !Sub arn:aws:s3:::${CURPath.Bucket}
Resource: !Sub arn:${AWS::Partition}:s3:::${CURPath.Bucket}
- Sid: CidAllowReadBucket
Effect: Allow
Action:
- s3:GetObject
- s3:GetObjectVersion
Resource: !Sub arn:aws:s3:::${CURPath.Bucket}/*
Resource: !Sub arn:${AWS::Partition}:s3:::${CURPath.Bucket}/*
Roles:
- !Ref QuickSightDataSourceRole

KmsPolicyForQuickSightDataSourceRole:
Type: AWS::IAM::Policy
Condition: NeedQuickSightDataSourceKMS
Expand All @@ -1187,7 +1233,7 @@ Resources:
DataSourceParameters:
AthenaParameters:
WorkGroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
RoleArn: !If [ UseQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRoleName}", !Ref AWS::NoValue ]
RoleArn: !If [ UseQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRoleName}", !Ref AWS::NoValue ]
Dismissed Show dismissed Hide dismissed
Permissions:
- Actions:
- 'quicksight:DescribeDataSource'
Expand Down Expand Up @@ -1295,7 +1341,7 @@ Resources:
- quicksight:DescribeRefreshSchedule
- quicksight:ListRefreshSchedules
Resource:
- !Sub arn:aws:quicksight:${AWS::Region}:${AWS::AccountId}:dataset/* # DataSetIDs are dynamic as well as schedule ids
- !Sub arn:${AWS::Partition}:quicksight:${AWS::Region}:${AWS::AccountId}:dataset/* # DataSetIDs are dynamic as well as schedule ids
- Effect: Allow
Action:
- athena:StartQueryExecution
Expand All @@ -1309,7 +1355,13 @@ Resources:
- athena:ListWorkGroups
- athena:GetDatabase
Resource: '*' # This is needed to allow Autodetect in CID-CMD

Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W11'
reason: "Lambda can install various QS and Athena resources. Cannot restrict."
- id: 'W28'
reason: "Need explicit name to give permissions"

DataLakeSettingsCidExecRolePerm:
Type: AWS::LakeFormation::Permissions
Expand Down Expand Up @@ -1510,6 +1562,13 @@ Resources:
return app.qs_url.format(dashboard_id=params['dashboard-id'], **app.qs_url_params)
Layers:
- !Ref CidResourceLambdaLayer
Metadata:
cfn_nag:
rules_to_suppress:
- id: 'W89'
reason: "No need to access to VPC resources"
- id: 'W92'
reason: "No need for reserved concurrency"

CidResourceLambdaLayer:
Type: AWS::Lambda::LayerVersion
Expand All @@ -1534,7 +1593,7 @@ Resources:
dashboard-id: cost_intelligence_dashboard
athena-workgroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
quicksight-datasource-id: !If [ NeedDatasource, !Select [ 1, !Split [ '/', !GetAtt CidAthenaDataSource.Arn]], 'CID-Athena-1']
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
athena-database: !If [NeedDatabase, !Ref CidDatabase, !Ref DatabaseName ]
glue-data-catalog: !Ref GlueDataCatalog
cur-table-name: !If [ NeedCURTable, !Ref MyCURTable, !Ref CURTableName ]
Expand All @@ -1554,7 +1613,7 @@ Resources:
dashboard-id: cudos
athena-workgroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
quicksight-datasource-id: !If [ NeedDatasource, !Select [ 1, !Split [ '/', !GetAtt CidAthenaDataSource.Arn]], 'CID-Athena-1']
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
athena-database: !If [NeedDatabase, !Ref CidDatabase, !Ref DatabaseName ]
glue-data-catalog: !Ref GlueDataCatalog
cur-table-name: !If [ NeedCURTable, !Ref MyCURTable, !Ref CURTableName ]
Expand All @@ -1576,7 +1635,7 @@ Resources:
dashboard-id: cudos-v5
athena-workgroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
quicksight-datasource-id: !If [ NeedDatasource, !Select [ 1, !Split [ '/', !GetAtt CidAthenaDataSource.Arn]], 'CID-Athena-1']
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
athena-database: !If [NeedDatabase, !Ref CidDatabase, !Ref DatabaseName ]
glue-data-catalog: !Ref GlueDataCatalog
cur-table-name: !If [ NeedCURTable, !Ref MyCURTable, !Ref CURTableName ]
Expand All @@ -1598,7 +1657,7 @@ Resources:
dashboard-id: kpi_dashboard
athena-workgroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
quicksight-datasource-id: !If [ NeedDatasource, !Select [ 1, !Split [ '/', !GetAtt CidAthenaDataSource.Arn]], 'CID-Athena-1']
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
athena-database: !If [NeedDatabase, !Ref CidDatabase, !Ref DatabaseName ]
glue-data-catalog: !Ref GlueDataCatalog
cur-table-name: !If [ NeedCURTable, !Ref MyCURTable, !Ref CURTableName ]
Expand All @@ -1623,7 +1682,7 @@ Resources:
dashboard-id: ta-organizational-view
athena-workgroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
quicksight-datasource-id: !If [ NeedDatasource, !Select [ 1, !Split [ '/', !GetAtt CidAthenaDataSource.Arn]], 'CID-Athena-1']
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
athena-database: !If [NeedDatabase, !Ref CidDatabase, !Ref DatabaseName ]
glue-data-catalog: !Ref GlueDataCatalog
cur-table-name: !If [ NeedCURTable, !Ref MyCURTable, !Ref CURTableName ]
Expand All @@ -1643,7 +1702,7 @@ Resources:
dashboard-id: compute-optimizer-dashboard
athena-workgroup: !If [ NeedAthenaWorkgroup, !Ref MyAthenaWorkGroup, !Ref AthenaWorkgroup ]
quicksight-datasource-id: !If [ NeedDatasource, !Select [ 1, !Split [ '/', !GetAtt CidAthenaDataSource.Arn]], 'CID-Athena-1']
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:aws:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
quicksight-datasource-role-arn: !If [ NeedQuickSightDataSourceRole, !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${QuickSightDataSourceRole}", "" ]
athena-database: !If [NeedDatabase, !Ref CidDatabase, !Ref DatabaseName ]
glue-data-catalog: !Ref GlueDataCatalog
cur-table-name: !If [ NeedCURTable, !Ref MyCURTable, !Ref CURTableName ]
Expand Down
8 changes: 8 additions & 0 deletions cfn-templates/cur-aggregation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ Resources:
rules_to_suppress:
- id: 'W35'
reason: "Data buckets would generate too much logs"
cfn-lint:
config:
ignore_checks:
- W3045 # Need to use AccessControl for replication

DestinationS3BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Expand Down Expand Up @@ -261,6 +265,10 @@ Resources:
rules_to_suppress:
- id: 'W35'
reason: "Data buckets would generate too much logs"
cfn-lint:
config:
ignore_checks:
- W3045 # Need to use AccessControl for replication

SourceS3BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Expand Down
2 changes: 1 addition & 1 deletion cid/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ def create_or_update_dataset(self, dataset_definition: dict, dataset_id: str=Non
athena_datasource = Datasource(raw={
'AthenaParameters':{},
"Id": datasource_id,
"Arn": f"arn:aws:quicksight:{self.base.session.region_name}:{self.base.account_id}:datasource/{datasource_id}",
"Arn": f"arn:{self.base.partition}:quicksight:{self.base.session.region_name}:{self.base.account_id}:datasource/{datasource_id}",
})
except Exception as exc:
raise CidCritical(
Expand Down
4 changes: 2 additions & 2 deletions cid/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ def export_analysis(qs, athena):
TemplateId=template_id,
GrantPermissions=[
{
"Principal": f'arn:aws:iam::{reader_account_id}:root' if reader_account_id != '*' else '*',
"Principal": f'arn:{qs.partition}:iam::{reader_account_id}:root' if reader_account_id != '*' else '*',
'Actions': [
"quicksight:DescribeTemplate",
]
Expand All @@ -363,7 +363,7 @@ def export_analysis(qs, athena):

for dataset in definition.get('DataSetIdentifierDeclarations', []):
# Hide region and account number of the source account
dataset["DataSetArn"] = 'arn:aws:quicksight:::dataset/' + dataset["DataSetArn"].split('/')[-1]
dataset["DataSetArn"] = f'arn:{qs.partition}:quicksight:::dataset/' + dataset["DataSetArn"].split('/')[-1]
dashboard_resource['data'] = yaml.safe_dump(definition)

resources['dashboards'][analysis['Name'].upper()] = dashboard_resource
Expand Down
Loading