Skip to content

Commit a62912a

Browse files
Merge branch 'main' into aea-5714-update-history-on-cancelled-prescriptions
2 parents df85906 + ed9b73d commit a62912a

File tree

15 files changed

+455
-55
lines changed

15 files changed

+455
-55
lines changed

.github/scripts/fix_cdk_json.sh

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,27 @@ if [ -z "${RUM_APP_NAME}" ]; then
131131
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
132132
fi
133133

134+
if [ -z "${SPLUNK_DELIVERY_STREAM}" ]; then
135+
SPLUNK_DELIVERY_STREAM=$(echo "$CF_LONDON_EXPORTS" | \
136+
jq \
137+
--arg EXPORT_NAME "lambda-resources:SplunkDeliveryStream" \
138+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
139+
fi
140+
141+
if [ -z "${SPLUNK_SUBSCRIPTION_FILTER_ROLE}" ]; then
142+
SPLUNK_SUBSCRIPTION_FILTER_ROLE=$(echo "$CF_LONDON_EXPORTS" | \
143+
jq \
144+
--arg EXPORT_NAME "lambda-resources:SplunkSubscriptionFilterRole" \
145+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
146+
fi
147+
if [ -z "${CLOUDFRONT_DISTRIBUTION_ARN}" ]; then
148+
CLOUDFRONT_DISTRIBUTION_ARN=$(echo "$CF_LONDON_EXPORTS" | \
149+
jq \
150+
--arg EXPORT_NAME "${SERVICE_NAME}-stateless-resources:cloudfrontDistribution:Arn" \
151+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
152+
fi
153+
154+
134155
# Acquire values externally
135156
## Get GitHub Actions runner IPs for use against WAF
136157
if [ -z "${GITHUB_ACTIONS_RUNNER_IPV4}" ]; then
@@ -166,6 +187,8 @@ if [ "$CDK_APP_NAME" == "StatefulResourcesApp" ]; then
166187
fix_list_key githubAllowListIpv4 "${GITHUB_ACTIONS_RUNNER_IPV4}"
167188
fix_list_key githubAllowListIpv6 "${GITHUB_ACTIONS_RUNNER_IPV6}"
168189
fix_boolean_number_key wafAllowGaRunnerConnectivity "${WAF_ALLOW_GA_RUNNER_CONNECTIVITY}"
190+
fix_string_key splunkDeliveryStream "${SPLUNK_DELIVERY_STREAM}"
191+
fix_string_key splunkSubscriptionFilterRole "${SPLUNK_SUBSCRIPTION_FILTER_ROLE}"
169192

170193
fix_boolean_number_key useMockOidc "${USE_MOCK_OIDC}"
171194
if [ "$USE_MOCK_OIDC" == "true" ]; then
@@ -183,10 +206,13 @@ if [ "$CDK_APP_NAME" == "StatefulResourcesApp" ]; then
183206
fix_string_key epsHostedZoneId "${EPS_HOSTED_ZONE_ID}"
184207

185208
fix_boolean_number_key allowAutoDeleteObjects "${AUTO_DELETE_OBJECTS}"
186-
# we may not have cloudfront distribution id if its a first deployment
209+
# we may not have cloudfront distribution details if its a first deployment
187210
if [ -n "${CLOUDFRONT_DISTRIBUTION_ID}" ]; then
188211
fix_string_key cloudfrontDistributionId "${CLOUDFRONT_DISTRIBUTION_ID}"
189212
fi
213+
if [ -n "${CLOUDFRONT_DISTRIBUTION_ARN}" ]; then
214+
fix_string_key cloudfrontDistributionArn "${CLOUDFRONT_DISTRIBUTION_ARN}"
215+
fi
190216
# if we have a rum log group arn, then we can set cwLogEnabled on the rum app
191217
if [ -n "${RUM_LOG_GROUP_ARN}" ]; then
192218
fix_boolean_number_key rumCloudwatchLogEnabled "true"

.github/workflows/release_all_stacks.yml

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,50 @@ jobs:
154154
role-session-name: prescription-clinical-tracker-ui-deployment
155155
output-credentials: true
156156

157-
- name: check first deployment
158-
id: check_first_deployment
157+
- name: check redeploy stateful stack
158+
id: check_redeploy_stateful_stack
159159
run: |
160-
# shellcheck disable=SC2140
161-
cloudfrontDistributionId=$(aws cloudformation list-exports --region eu-west-2 --query "Exports[?Name=='"${{ inputs.SERVICE_NAME }}-stateless-resources:cloudfrontDistribution:Id"'].Value" --output text)
162-
if [ -z "${cloudfrontDistributionId}" ]; then
163-
FIRST_DEPLOYMENT="true"
164-
echo "This is the first deployment"
165-
else
166-
FIRST_DEPLOYMENT="false"
167-
echo "This is not the first deployment"
160+
CF_LONDON_EXPORTS=$(aws cloudformation list-exports --region eu-west-2 --output json)
161+
CLOUDFRONT_DISTRIBUTION_ID=$(echo "$CF_LONDON_EXPORTS" | \
162+
jq \
163+
--arg EXPORT_NAME "${{ inputs.SERVICE_NAME }}-stateless-resources:cloudfrontDistribution:Id" \
164+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
165+
CLOUDFRONT_DISTRIBUTION_ARN=$(echo "$CF_LONDON_EXPORTS" | \
166+
jq \
167+
--arg EXPORT_NAME "${{ inputs.SERVICE_NAME }}-stateless-resources:cloudfrontDistribution:Arn" \
168+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
169+
RUM_LOG_GROUP_ARN=$(echo "$CF_LONDON_EXPORTS" | \
170+
jq \
171+
--arg EXPORT_NAME "${{ inputs.SERVICE_NAME }}-stateful-resources:rum:logGroup:arn" \
172+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
173+
RUM_APP_NAME=$(echo "$CF_LONDON_EXPORTS" | \
174+
jq \
175+
--arg EXPORT_NAME "${{ inputs.SERVICE_NAME }}-stateful-resources:rum:rumApp:Name" \
176+
-r '.Exports[] | select(.Name == $EXPORT_NAME) | .Value')
177+
REDEPLOY_STATEFUL_STACK="false"
178+
179+
if [ -z "${CLOUDFRONT_DISTRIBUTION_ID}" ]; then
180+
echo "CLOUDFRONT_DISTRIBUTION_ID not found - setting redeploy stateful stack to true"
181+
REDEPLOY_STATEFUL_STACK="true"
182+
fi
183+
if [ -z "${CLOUDFRONT_DISTRIBUTION_ARN}" ]; then
184+
echo "CLOUDFRONT_DISTRIBUTION_ARN not found - setting redeploy stateful stack to true"
185+
REDEPLOY_STATEFUL_STACK="true"
168186
fi
169-
echo "FIRST_DEPLOYMENT=$FIRST_DEPLOYMENT" >> "$GITHUB_OUTPUT"
187+
if [ -z "${RUM_LOG_GROUP_ARN}" ]; then
188+
echo "RUM_LOG_GROUP_ARN not found - setting redeploy stateful stack to true"
189+
REDEPLOY_STATEFUL_STACK="true"
190+
fi
191+
if [ -z "${RUM_APP_NAME}" ]; then
192+
echo "RUM_APP_NAME not found - setting redeploy stateful stack to true"
193+
REDEPLOY_STATEFUL_STACK="true"
194+
fi
195+
196+
if [ "${REDEPLOY_STATEFUL_STACK}" == "false" ]; then
197+
echo "Everything already set - setting redeploy stateful stack to false"
198+
fi
199+
200+
echo "REDEPLOY_STATEFUL_STACK=$REDEPLOY_STATEFUL_STACK" >> "$GITHUB_OUTPUT"
170201
shell: bash
171202

172203
- name: fix cdk.json for deployment stateful stack
@@ -430,7 +461,7 @@ jobs:
430461
fi
431462
432463
- name: fix cdk.json for deployment for stateful stack redeployment
433-
if: ${{ steps.check_first_deployment.outputs.FIRST_DEPLOYMENT == 'true' }}
464+
if: ${{ steps.check_redeploy_stateful_stack.outputs.REDEPLOY_STATEFUL_STACK == 'true' }}
434465
run: |
435466
./.github/scripts/fix_cdk_json.sh .build/stateful_resources.json
436467
env:
@@ -472,7 +503,7 @@ jobs:
472503
CLOUDFRONT_ORIGIN_CUSTOM_HEADER: ${{secrets.CLOUDFRONT_ORIGIN_CUSTOM_HEADER }}
473504

474505
- name: Show diff for stateful stack redeployment
475-
if: ${{ steps.check_first_deployment.outputs.FIRST_DEPLOYMENT == 'true' }}
506+
if: ${{ steps.check_redeploy_stateful_stack.outputs.REDEPLOY_STATEFUL_STACK == 'true' }}
476507
run: |
477508
docker run \
478509
-v "$(pwd)/.build":/home/cdkuser/workspace/ \
@@ -488,7 +519,7 @@ jobs:
488519
shell: bash
489520

490521
- name: Deploy code for stateful stack redeployment
491-
if: ${{ steps.check_first_deployment.outputs.FIRST_DEPLOYMENT == 'true' }}
522+
if: ${{ steps.check_redeploy_stateful_stack.outputs.REDEPLOY_STATEFUL_STACK == 'true' }}
492523
run: |
493524
docker run \
494525
-v "$(pwd)/.build":/home/cdkuser/workspace/ \

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ cdk-synth-stateful-resources-no-mock:
213213
ALLOW_LOCALHOST_ACCESS=false \
214214
WAF_ALLOW_GA_RUNNER_CONNECTIVITY=true \
215215
CLOUDFRONT_ORIGIN_CUSTOM_HEADER=foo \
216+
SPLUNK_DELIVERY_STREAM=foo \
217+
SPLUNK_SUBSCRIPTION_FILTER_ROLE=foo \
216218
DO_NOT_GET_AWS_EXPORT=true \
217219
USE_ZONE_APEX=false \
218220
./.github/scripts/fix_cdk_json.sh .local_config/stateful_app.config.json
@@ -304,6 +306,8 @@ cdk-synth-stateful-resources-mock:
304306
ALLOW_LOCALHOST_ACCESS=false \
305307
WAF_ALLOW_GA_RUNNER_CONNECTIVITY=true \
306308
CLOUDFRONT_ORIGIN_CUSTOM_HEADER=foo \
309+
SPLUNK_DELIVERY_STREAM=foo \
310+
SPLUNK_SUBSCRIPTION_FILTER_ROLE=foo \
307311
DO_NOT_GET_AWS_EXPORT=true \
308312
USE_ZONE_APEX=false \
309313
./.github/scripts/fix_cdk_json.sh .local_config/stateful_app.config.json

packages/cdk/nagSuppressions.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,20 @@ export const nagSuppressions = (stack: Stack) => {
246246
}
247247
]
248248
)
249+
250+
safeAddNagSuppression(
251+
stack,
252+
"/StatelessStack/CloudfrontDistribution/CloudfrontDistribution/Resource",
253+
[
254+
{
255+
id: "AwsSolutions-CFR3",
256+
reason: "Suppress error for not having access logging. We send logs to cloudwatch instead of S3"
257+
}
258+
]
259+
)
260+
249261
}
262+
250263
}
251264

252265
const safeAddNagSuppression = (stack: Stack, path: string, suppressions: Array<NagPackSuppression>) => {

packages/cdk/resources/CloudfrontDistribution.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
RecordTarget
1515
} from "aws-cdk-lib/aws-route53"
1616
import {CloudFrontTarget} from "aws-cdk-lib/aws-route53-targets"
17-
import {IBucket} from "aws-cdk-lib/aws-s3"
1817
import {Construct} from "constructs"
1918

2019
/**
@@ -31,7 +30,6 @@ export interface CloudfrontDistributionProps {
3130
readonly hostedZone: IHostedZone
3231
readonly shortCloudfrontDomain: string
3332
readonly fullCloudfrontDomain: string
34-
readonly cloudfrontLoggingBucket: IBucket
3533
readonly cloudfrontCert: ICertificate
3634
readonly webAclAttributeArn: string
3735
readonly wafAllowGaRunnerConnectivity: boolean
@@ -56,17 +54,16 @@ export class CloudfrontDistribution extends Construct {
5654
minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_2_2021,
5755
sslSupportMethod: SSLMethod.SNI,
5856
publishAdditionalMetrics: true,
59-
enableLogging: true,
60-
logBucket: props.cloudfrontLoggingBucket,
61-
logFilePrefix: `${props.stackName}/`,
57+
enableLogging: false,
6258
logIncludesCookies: true, // may actually want to be false, don't know if it includes names of cookies or contents
6359
defaultBehavior: props.defaultBehavior,
6460
additionalBehaviors: props.additionalBehaviors,
6561
errorResponses: props.errorResponses,
6662
geoRestriction: {
6763
locations: props.wafAllowGaRunnerConnectivity ? ["GB", "JE", "GG", "IM", "US"] : ["GB", "JE", "GG", "IM"],
6864
restrictionType: "whitelist"
69-
}
65+
},
66+
webAclId: props.webAclAttributeArn
7067
})
7168

7269
if (props.shortCloudfrontDomain === "APEX_DOMAIN") {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {Names} from "aws-cdk-lib"
2+
import {
3+
CfnDelivery,
4+
CfnDeliveryDestination,
5+
CfnDeliverySource,
6+
ILogGroup,
7+
LogGroup
8+
} from "aws-cdk-lib/aws-logs"
9+
import {Construct} from "constructs"
10+
11+
export interface CloudfrontLogDeliveryProps {
12+
readonly cloudfrontLogGroup: ILogGroup
13+
readonly cloudfrontDistributionArn: string
14+
}
15+
16+
export class CloudfrontLogDelivery extends Construct {
17+
public readonly logGroup: LogGroup
18+
19+
constructor(scope: Construct, id: string, props: CloudfrontLogDeliveryProps) {
20+
super(scope, id)
21+
const distDeliveryDestination = new CfnDeliveryDestination(this, "DistributionDeliveryDestination", {
22+
name: `${Names.uniqueResourceName(this, {maxLength:55})}-dest`,
23+
destinationResourceArn: props.cloudfrontLogGroup.logGroupArn,
24+
outputFormat: "json"
25+
})
26+
27+
// add the delivery source and delivery for cloudfront logs
28+
// this can only be done once the cloudfront distribution is created in the stateless stack
29+
if (props.cloudfrontDistributionArn) {
30+
const distDeliverySource = new CfnDeliverySource(this, "DistributionDeliverySource", {
31+
name: `${Names.uniqueResourceName(this, {maxLength:55})}-src`,
32+
logType: "ACCESS_LOGS",
33+
resourceArn: props.cloudfrontDistributionArn
34+
})
35+
36+
const delivery = new CfnDelivery(this, "DistributionDelivery", {
37+
deliverySourceName: distDeliverySource.name,
38+
deliveryDestinationArn: distDeliveryDestination.attrArn
39+
})
40+
delivery.node.addDependency(distDeliverySource)
41+
42+
}
43+
}
44+
45+
}

packages/cdk/resources/WebApplicationFirewall.ts

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Construct} from "constructs"
2-
import * as wafv2 from "aws-cdk-lib/aws-wafv2"
2+
import {CfnIPSet, CfnLoggingConfiguration, CfnWebACL} from "aws-cdk-lib/aws-wafv2"
33

44
/**
55
* WAF ACL and supporting resources
@@ -11,35 +11,28 @@ export interface WebACLProps {
1111
readonly githubAllowListIpv4: Array<string>
1212
readonly githubAllowListIpv6: Array<string>
1313
readonly wafAllowGaRunnerConnectivity: boolean
14+
readonly allowedHeaders?: Map<string, string>
1415
readonly scope: string
16+
readonly wafLogGroupName: string
1517
}
1618

1719
export class WebACL extends Construct {
18-
public readonly githubAllowListIpv4: wafv2.CfnIPSet
19-
public readonly githubAllowListIpv6: wafv2.CfnIPSet
20+
public readonly githubAllowListIpv4: CfnIPSet
21+
public readonly githubAllowListIpv6: CfnIPSet
2022
public readonly wafAllowGaRunnerConnectivity: boolean
21-
public readonly webAcl: wafv2.CfnWebACL
23+
public readonly webAcl: CfnWebACL
2224
public readonly attrArn: string
2325
public readonly allowedHeaders?: Map<string, string>
2426

2527
public constructor(
2628
scope: Construct,
2729
id: string,
28-
props: {
29-
serviceName: string
30-
rateLimitTransactions: number
31-
rateLimitWindowSeconds: number
32-
githubAllowListIpv4: Array<string>
33-
githubAllowListIpv6: Array<string>
34-
wafAllowGaRunnerConnectivity: boolean
35-
allowedHeaders?: Map<string, string>
36-
scope: string
37-
}
30+
props: WebACLProps
3831
) {
3932
super(scope, id)
4033

4134
if (props.wafAllowGaRunnerConnectivity && props.githubAllowListIpv4.length > 0) {
42-
this.githubAllowListIpv4 = new wafv2.CfnIPSet(this, "githubAllowListIpv4", {
35+
this.githubAllowListIpv4 = new CfnIPSet(this, "githubAllowListIpv4", {
4336
addresses: props.githubAllowListIpv4,
4437
ipAddressVersion: "IPV4",
4538
scope: props.scope,
@@ -49,7 +42,7 @@ export class WebACL extends Construct {
4942
}
5043

5144
if (props.wafAllowGaRunnerConnectivity && props.githubAllowListIpv6.length > 0) {
52-
this.githubAllowListIpv6 = new wafv2.CfnIPSet(this, "githubAllowListIpv6", {
45+
this.githubAllowListIpv6 = new CfnIPSet(this, "githubAllowListIpv6", {
5346
addresses: props.githubAllowListIpv6,
5447
ipAddressVersion: "IPV6",
5548
scope: props.scope,
@@ -58,7 +51,7 @@ export class WebACL extends Construct {
5851
})
5952
}
6053

61-
const rules: Array<wafv2.CfnWebACL.RuleProperty> = []
54+
const rules: Array<CfnWebACL.RuleProperty> = []
6255
let nextPriority = 0
6356

6457
if (props.wafAllowGaRunnerConnectivity && props.githubAllowListIpv4.length > 0) {
@@ -214,7 +207,7 @@ export class WebACL extends Construct {
214207
}
215208
})
216209

217-
const webAcl = new wafv2.CfnWebACL(this, "CloudfrontWebAcl", {
210+
const webAcl = new CfnWebACL(this, "CloudfrontWebAcl", {
218211
name: `${props.serviceName}-WebAcl`,
219212
defaultAction: {allow: {}},
220213
scope: props.scope,
@@ -232,6 +225,11 @@ export class WebACL extends Construct {
232225
]
233226
})
234227

228+
new CfnLoggingConfiguration(scope, "webAclLoggingConfiguration", {
229+
logDestinationConfigs: [ props.wafLogGroupName ],
230+
resourceArn: webAcl.attrArn // Arn of Acl
231+
})
232+
235233
this.webAcl = webAcl
236234
this.attrArn = webAcl.attrArn
237235
}

0 commit comments

Comments
 (0)