Skip to content
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
1 change: 0 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": [
"packages/slackBotFunction",
"packages/createIndexFunction"
],
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
Expand Down
2 changes: 2 additions & 0 deletions .gitallowed
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ token: props\.slackBotToken
secretValue: JSON\.stringify\(\{token: props\.slackBotToken\}\)
token = slack_event_data\["bot_token"\]
client = WebClient\(token=token\)
client = WebClient\(token=slack_event_data\["bot_token"\]\)
context accountId=123456789012
6 changes: 6 additions & 0 deletions .github/scripts/fix_cdk_json.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ fix_boolean_number_key() {
mv .build/cdk.new.json .build/cdk.json
}

CFN_DRIFT_DETECTION_GROUP="epsam"
if [[ "$STACK_NAME" =~ -pr-[0-9]+$ ]]; then
CFN_DRIFT_DETECTION_GROUP="epsam-pull-request"
fi

# go through all the key values we need to set
fix_string_key accountId "${ACCOUNT_ID}"
fix_string_key stackName "${STACK_NAME}"
Expand All @@ -44,3 +49,4 @@ fix_string_key logRetentionInDays "${LOG_RETENTION_IN_DAYS}"
fix_string_key logLevel "${LOG_LEVEL}"
fix_string_key slackBotToken "${SLACK_BOT_TOKEN}"
fix_string_key slackSigningSecret "${SLACK_SIGNING_SECRET}"
fix_string_key cfnDriftDetectionGroup "${CFN_DRIFT_DETECTION_GROUP}"
1 change: 0 additions & 1 deletion .github/workflows/cdk_package_code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ jobs:
- name: Build Python Lambda Functions
run: |
pip3 install -r packages/slackBotFunction/requirements.txt -t packages/slackBotFunction
pip3 install -r packages/createIndexFunction/requirements.txt -t packages/createIndexFunction
pip3 install -r packages/syncKnowledgeBaseFunction/requirements.txt -t packages/syncKnowledgeBaseFunction

- name: 'Tar files'
Expand Down
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ repos:
types_or: [sh, shell]
pass_filenames: false

- id: lint-cdk
name: Lint cdk
entry: npm
args: ["run", "--prefix=packages/cdk", "lint"]
language: system
files: ^packages\/cdk
types_or: [ts, tsx, javascript, jsx, json]
pass_filenames: false

- repo: local
hooks:
- id: git-secrets
Expand Down
4 changes: 0 additions & 4 deletions .vscode/eps-assist-me.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
"name": "packages/cdk",
"path": "../packages/cdk"
},
{
"name": "packages/createIndexFunction",
"path": "../packages/createIndexFunction"
},
{
"name": "packages/slackBotFunction",
"path": "../packages/slackBotFunction"
Expand Down
16 changes: 7 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ install: install-python install-hooks install-node

install-python:
poetry install
cd packages/createIndexFunction && pip install -r requirements.txt && pip install -r requirements-test.txt
cd packages/slackBotFunction && pip install -r requirements.txt && pip install -r requirements-test.txt
cd packages/syncKnowledgeBaseFunction && pip install -r requirements.txt && pip install -r requirements-test.txt

Expand All @@ -30,7 +29,10 @@ git-secrets-docker-setup:
export LOCAL_WORKSPACE_FOLDER=$(pwd)
docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v4.0.4/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets .

lint: lint-githubactions lint-githubaction-scripts lint-black lint-flake8
lint: lint-githubactions lint-githubaction-scripts lint-black lint-flake8 lint-node

lint-node:
npm run lint --workspace packages/cdk

lint-githubactions:
actionlint
Expand All @@ -46,15 +48,12 @@ lint-flake8:
poetry run flake8 .

test:
cd packages/createIndexFunction && PYTHONPATH=. COVERAGE_FILE=coverage/.coverage python -m pytest
cd packages/slackBotFunction && PYTHONPATH=. COVERAGE_FILE=coverage/.coverage python -m pytest
cd packages/syncKnowledgeBaseFunction && PYTHONPATH=. COVERAGE_FILE=coverage/.coverage python -m pytest

clean:
rm -rf packages/cdk/coverage
rm -rf packages/cdk/lib
rm -rf packages/createIndexFunction/coverage
rm -rf packages/createIndexFunction/.coverage
rm -rf packages/slackBotFunction/coverage
rm -rf packages/slackBotFunction/.coverage
rm -rf packages/syncKnowledgeBaseFunction/coverage
Expand Down Expand Up @@ -99,19 +98,18 @@ cdk-deploy: guard-STACK_NAME
--context logRetentionInDays=$$LOG_RETENTION_IN_DAYS \
--context slackBotToken=$$SLACK_BOT_TOKEN \
--context slackSigningSecret=$$SLACK_SIGNING_SECRET

cdk-synth:
npx cdk synth \
--quiet \
--app "npx ts-node --prefer-ts-exts packages/cdk/bin/EpsAssistMeApp.ts" \
--context accountId=undefined \
--context accountId=123456789012 \
--context stackName=epsam \
--context versionNumber=undefined \
--context commitId=undefined \
--context logRetentionInDays=30 \
--context slackBotToken=dummy \
--context slackSigningSecret=dummy
./scripts/fix_cfn_guard.sh
--context slackSigningSecret=dummy \
--context cfnDriftDetectionGroup=dummy

cdk-diff:
npx cdk diff \
Expand Down
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ packages/
│ │ └── RestApiGateway/ # API Gateway specific constructs
│ ├── resources/ # AWS resource definitions
│ └── stacks/ # CDK stack definitions
├── createIndexFunction/ # Lambda function for OpenSearch index management
│ ├── app/ # Application code
│ │ ├── config/ # Configuration and environment variables
│ │ └── handler.py # Lambda handler
│ └── tests/ # Unit tests
├── slackBotFunction/ # Lambda function for Slack bot integration
│ ├── app/ # Application code
│ │ ├── config/ # Configuration and environment variables
Expand Down
64 changes: 47 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/cdk/bin/EpsAssistMeApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const accountId = app.node.tryGetContext("accountId")
const stackName = app.node.tryGetContext("stackName")
const version = app.node.tryGetContext("versionNumber")
const commit = app.node.tryGetContext("commitId")
const cfnDriftDetectionGroup = app.node.tryGetContext("cfnDriftDetectionGroup")

Aspects.of(app).add(new AwsSolutionsChecks({verbose: true}))

Expand All @@ -25,6 +26,7 @@ Tags.of(app).add("accountId", accountId)
Tags.of(app).add("stackName", stackName)
Tags.of(app).add("version", version)
Tags.of(app).add("commit", commit)
Tags.of(app).add("cfnDriftDetectionGroup", cfnDriftDetectionGroup)

const EpsAssistMe = new EpsAssistMeStack(app, "EpsAssistMeStack", {
env: {
Expand Down
26 changes: 6 additions & 20 deletions packages/cdk/bin/utils/appUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const findResourcesByPattern = (construct: IConstruct, patterns: Array<string>):
const search = (node: IConstruct): void => {
if (node instanceof CfnResource) {
for (const pattern of patterns) {
if (node.logicalId.includes(pattern) && !seen.has(node.logicalId)) {
if (node.node.id.includes(pattern) && !seen.has(node.logicalId)) {
matches.push(node)
seen.add(node.logicalId)
break
Expand Down Expand Up @@ -63,23 +63,9 @@ export const applyCfnGuardSuppressions = (stack: Stack): void => {
// Suppress all cfn-guard checks for all Lambda functions (including implicit CDK-generated ones)
const allLambdas = findResourcesByType(stack, "AWS::Lambda::Function")
addSuppressions(allLambdas, ["LAMBDA_DLQ_CHECK", "LAMBDA_INSIDE_VPC", "LAMBDA_CONCURRENCY_CHECK"])

// Suppress S3 bucket guard checks
const bucketResources = findResourcesByPattern(stack, ["Bucket", "Docs", "Storage"])
addSuppressions(
bucketResources,
[
"S3_BUCKET_REPLICATION_ENABLED",
"S3_BUCKET_LOGGING_ENABLED",
"S3_BUCKET_DEFAULT_LOCK_ENABLED"
]
)

// Suppress S3 policy guard checks
const policyResources = findResourcesByPattern(stack, ["Policy", "BucketPolicy"])
addSuppressions(policyResources, ["S3_BUCKET_SSL_REQUESTS_ONLY"])

// Suppress API Gateway stage guard checks
const stageResources = findResourcesByPattern(stack, ["Stage", "DeploymentStage"])
addSuppressions(stageResources, ["API_GW_CACHE_ENABLED_AND_ENCRYPTED"])
const permissionResources = findResourcesByPattern(stack, [
"ApiPermission.Test.EpsAssistMeStackApisEpsAssistApiGateway1E1CF19C.POST..slack.events",
"AllowBucketNotificationsToEpsAssistMeStackFunctionsSyncKnowledgeBaseFunctionepsamSyncKnowledgeBaseFunction94D011F3"
])
addSuppressions(permissionResources, ["LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED"])
}
11 changes: 7 additions & 4 deletions packages/cdk/constructs/DynamoDbTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ export class DynamoDbTable extends Construct {
constructor(scope: Construct, id: string, props: DynamoDbTableProps) {
super(scope, id)

this.kmsKey = new Key(this, "TableKey", {
const kmsKey = new Key(this, "TableKey", {
enableKeyRotation: true,
description: `KMS key for ${props.tableName} DynamoDB table encryption`,
removalPolicy: RemovalPolicy.DESTROY
})

this.kmsKey.addAlias(`alias/${props.tableName}-dynamodb-key`)
kmsKey.addAlias(`alias/${props.tableName}-dynamodb-key`)

this.table = new TableV2(this, props.tableName, {
const table = new TableV2(this, props.tableName, {
tableName: props.tableName,
partitionKey: props.partitionKey,
sortKey: props.sortKey,
Expand All @@ -46,7 +46,10 @@ export class DynamoDbTable extends Construct {
pointInTimeRecoveryEnabled: true
},
removalPolicy: RemovalPolicy.DESTROY,
encryption: TableEncryptionV2.customerManagedKey(this.kmsKey)
encryption: TableEncryptionV2.customerManagedKey(kmsKey)
})

this.kmsKey = kmsKey
this.table = table
}
}
Loading