From 548ac91cf23b539513170e0183e263ff84b2fbb4 Mon Sep 17 00:00:00 2001 From: Pete F Date: Mon, 23 Dec 2024 16:11:38 +0000 Subject: [PATCH 1/4] Named export for poller lambda handlers --- cdk/lib/__snapshots__/newswires.test.ts.snap | 4 ++-- cdk/lib/constructs/pollerLambda.ts | 2 +- poller-lambdas/localRun.ts | 2 +- poller-lambdas/src/index.ts | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cdk/lib/__snapshots__/newswires.test.ts.snap b/cdk/lib/__snapshots__/newswires.test.ts.snap index 4516e2f..bea49af 100644 --- a/cdk/lib/__snapshots__/newswires.test.ts.snap +++ b/cdk/lib/__snapshots__/newswires.test.ts.snap @@ -438,7 +438,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` }, }, "FunctionName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda", - "Handler": "index.EXAMPLE_fixed_frequency", + "Handler": "index.handlers.EXAMPLE_fixed_frequency", "LoggingConfig": { "LogFormat": "JSON", }, @@ -1260,7 +1260,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` }, }, "FunctionName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda", - "Handler": "index.EXAMPLE_long_polling", + "Handler": "index.handlers.EXAMPLE_long_polling", "LoggingConfig": { "LogFormat": "JSON", }, diff --git a/cdk/lib/constructs/pollerLambda.ts b/cdk/lib/constructs/pollerLambda.ts index e6aabf9..d5f470c 100644 --- a/cdk/lib/constructs/pollerLambda.ts +++ b/cdk/lib/constructs/pollerLambda.ts @@ -98,7 +98,7 @@ export class PollerLambda { }, memorySize: pollerConfig.overrideLambdaMemoryMB ?? 128, timeout, - handler: `index.${pollerId}`, // see programmatically generated exports in poller-lambdas/src/index.ts + handler: `index.handlers.${pollerId}`, // see programmatically generated exports in poller-lambdas/src/index.ts fileName: `poller-lambdas.zip`, // shared zip for all the poller-lambdas }); diff --git a/poller-lambdas/localRun.ts b/poller-lambdas/localRun.ts index 51f81bb..b00d1ce 100644 --- a/poller-lambdas/localRun.ts +++ b/poller-lambdas/localRun.ts @@ -8,7 +8,7 @@ import { POLLERS_CONFIG, } from '../shared/pollers'; import { sqs } from './src/aws'; -import handlers from './src/index'; +import { handlers } from './src/index'; import type { HandlerInputSqsPayload } from './src/types'; const fakeInvoke = async ( diff --git a/poller-lambdas/src/index.ts b/poller-lambdas/src/index.ts index 63c420c..cc33068 100644 --- a/poller-lambdas/src/index.ts +++ b/poller-lambdas/src/index.ts @@ -99,8 +99,7 @@ const pollerWrapper = } }; -// eslint-disable-next-line import/no-default-export -- we need this to expose the pollers as named handlers but the shape verified with 'satisfies' keyword -export default { +export const handlers = { EXAMPLE_long_polling: pollerWrapper(EXAMPLE_long_polling), EXAMPLE_fixed_frequency: pollerWrapper(EXAMPLE_fixed_frequency), } satisfies Record< From d878e2fee6628a1d19cfddd77db51d9a47fe5a23 Mon Sep 17 00:00:00 2001 From: Pete F Date: Thu, 19 Dec 2024 13:21:52 +0000 Subject: [PATCH 2/4] Minimal Reuters poller setup --- cdk/lib/__snapshots__/newswires.test.ts.snap | 4071 +++++++---------- cdk/lib/__snapshots__/riffraff.test.ts.snap | 43 +- package.json | 16 +- poller-lambdas/src/index.ts | 8 +- .../src/pollers/reuters/reutersPoller.ts | 18 + shared/pollers.ts | 5 +- 6 files changed, 1667 insertions(+), 2494 deletions(-) create mode 100644 poller-lambdas/src/pollers/reuters/reutersPoller.ts diff --git a/cdk/lib/__snapshots__/newswires.test.ts.snap b/cdk/lib/__snapshots__/newswires.test.ts.snap index bea49af..ab7585e 100644 --- a/cdk/lib/__snapshots__/newswires.test.ts.snap +++ b/cdk/lib/__snapshots__/newswires.test.ts.snap @@ -18,11 +18,6 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "GuLambdaThrottlingAlarm", "GuAlarm", "GuAlarm", - "GuLambdaFunction", - "GuLambdaErrorPercentageAlarm", - "GuLambdaThrottlingAlarm", - "GuAlarm", - "GuAlarm", "GuGetS3ObjectsPolicy", "GuGetS3ObjectsPolicy", "GuSubnetListParameter", @@ -356,106 +351,54 @@ exports[`The Newswires stack matches the snapshot 1`] = ` }, "Type": "Guardian::DNS::RecordSet", }, - "EXAMPLEfixedfrequencyLambdaD9A07041": { - "DependsOn": [ - "EXAMPLEfixedfrequencyLambdaServiceRoleDefaultPolicy272A9D10", - "EXAMPLEfixedfrequencyLambdaServiceRoleBA2F232F", - ], + "GetDistributablePolicyNewswires3D555C70": { "Properties": { - "Architectures": [ - "arm64", - ], - "Code": { - "S3Bucket": { - "Ref": "DistributionBucketName", - }, - "S3Key": "editorial-feeds/TEST/EXAMPLE_fixed_frequency_poller_lambda/poller-lambdas.zip", - }, - "Environment": { - "Variables": { - "APP": "EXAMPLE_fixed_frequency_poller_lambda", - "INGESTION_LAMBDA_QUEUE_URL": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputRefMockSourceQueue20B4D8C006FBA8DA", - }, - "OWN_QUEUE_URL": { - "Ref": "EXAMPLEfixedfrequencyLambdaQueueF55F5480", - }, - "SECRET_NAME": { - "Fn::Join": [ - "-", - [ - { - "Fn::Select": [ - 0, - { - "Fn::Split": [ - "-", - { - "Fn::Select": [ - 6, - { - "Fn::Split": [ - ":", - { - "Ref": "EXAMPLEfixedfrequencySecretCB2DCB8C", - }, - ], - }, - ], - }, - ], - }, - ], - }, - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - "-", - { - "Fn::Select": [ - 6, - { - "Fn::Split": [ - ":", - { - "Ref": "EXAMPLEfixedfrequencySecretCB2DCB8C", - }, - ], - }, - ], - }, - ], - }, - ], - }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:GetObject", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "DistributionBucketName", + }, + "/editorial-feeds/TEST/newswires/*", + ], ], - ], + }, }, - "STACK": "editorial-feeds", - "STAGE": "TEST", - }, - }, - "FunctionName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda", - "Handler": "index.handlers.EXAMPLE_fixed_frequency", - "LoggingConfig": { - "LogFormat": "JSON", - }, - "MemorySize": 128, - "RecursiveLoop": "Allow", - "ReservedConcurrentExecutions": 2, - "Role": { - "Fn::GetAtt": [ - "EXAMPLEfixedfrequencyLambdaServiceRoleBA2F232F", - "Arn", ], + "Version": "2012-10-17", }, - "Runtime": "nodejs20.x", + "PolicyName": "GetDistributablePolicyNewswires3D555C70", + "Roles": [ + { + "Ref": "InstanceRoleNewswiresC10A0615", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "GuHttpsEgressSecurityGroupNewswiresEF9436B0": { + "Properties": { + "GroupDescription": "Allow all outbound HTTPS traffic", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound HTTPS traffic", + "FromPort": 443, + "IpProtocol": "tcp", + "ToPort": 443, + }, + ], "Tags": [ { "Key": "App", - "Value": "EXAMPLE_fixed_frequency_poller_lambda", + "Value": "newswires", }, { "Key": "gu:cdk:version", @@ -474,11 +417,76 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Timeout": 60, + "VpcId": { + "Ref": "VpcId", + }, }, - "Type": "AWS::Lambda::Function", + "Type": "AWS::EC2::SecurityGroup", + }, + "GuHttpsEgressSecurityGroupNewswiresfromNewswiresLoadBalancerNewswiresSecurityGroup255ABDD190005C31A09F": { + "Properties": { + "Description": "Load balancer to target", + "FromPort": 9000, + "GroupId": { + "Fn::GetAtt": [ + "GuHttpsEgressSecurityGroupNewswiresEF9436B0", + "GroupId", + ], + }, + "IpProtocol": "tcp", + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "LoadBalancerNewswiresSecurityGroupF93D2107", + "GroupId", + ], + }, + "ToPort": 9000, + }, + "Type": "AWS::EC2::SecurityGroupIngress", + }, + "GuLogShippingPolicy981BFE5A": { + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kinesis:Describe*", + "kinesis:Put*", + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:kinesis:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":stream/", + { + "Ref": "LoggingStreamName", + }, + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "GuLogShippingPolicy981BFE5A", + "Roles": [ + { + "Ref": "InstanceRoleNewswiresC10A0615", + }, + ], + }, + "Type": "AWS::IAM::Policy", }, - "EXAMPLEfixedfrequencyLambdaErrorPercentageAlarmForLambda1B4D14B2": { + "High5xxPercentageAlarmNewswiresC0FCCFC5": { "Properties": { "ActionsEnabled": true, "AlarmActions": [ @@ -505,40 +513,56 @@ exports[`The Newswires stack matches the snapshot 1`] = ` ], }, ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda is erroring.", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda_Error_Alarm", + "AlarmDescription": "newswires exceeded 10% error rate", + "AlarmName": "High 5XX error percentage from newswires in TEST", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ { - "Expression": "100*m1/m2", + "Expression": "100*(m1+m2)/m3", "Id": "expr_1", - "Label": { - "Fn::Join": [ - "", - [ - "Error % of ", + "Label": "% of 5XX responses served for newswires (load balancer and instances combined)", + }, + { + "Id": "m1", + "MetricStat": { + "Metric": { + "Dimensions": [ { - "Ref": "EXAMPLEfixedfrequencyLambdaD9A07041", + "Name": "LoadBalancer", + "Value": { + "Fn::GetAtt": [ + "LoadBalancerNewswires3B8BBCB3", + "LoadBalancerFullName", + ], + }, }, ], - ], + "MetricName": "HTTPCode_ELB_5XX_Count", + "Namespace": "AWS/ApplicationELB", + }, + "Period": 60, + "Stat": "Sum", }, + "ReturnData": false, }, { - "Id": "m1", + "Id": "m2", "MetricStat": { "Metric": { "Dimensions": [ { - "Name": "FunctionName", + "Name": "LoadBalancer", "Value": { - "Ref": "EXAMPLEfixedfrequencyLambdaD9A07041", + "Fn::GetAtt": [ + "LoadBalancerNewswires3B8BBCB3", + "LoadBalancerFullName", + ], }, }, ], - "MetricName": "Errors", - "Namespace": "AWS/Lambda", + "MetricName": "HTTPCode_Target_5XX_Count", + "Namespace": "AWS/ApplicationELB", }, "Period": 60, "Stat": "Sum", @@ -546,19 +570,22 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "ReturnData": false, }, { - "Id": "m2", + "Id": "m3", "MetricStat": { "Metric": { "Dimensions": [ { - "Name": "FunctionName", + "Name": "LoadBalancer", "Value": { - "Ref": "EXAMPLEfixedfrequencyLambdaD9A07041", + "Fn::GetAtt": [ + "LoadBalancerNewswires3B8BBCB3", + "LoadBalancerFullName", + ], }, }, ], - "MetricName": "Invocations", - "Namespace": "AWS/Lambda", + "MetricName": "RequestCount", + "Namespace": "AWS/ApplicationELB", }, "Period": 60, "Stat": "Sum", @@ -566,31 +593,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "ReturnData": false, }, ], - "OKActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], - }, - ], - "Tags": [ + "Tags": [ { "Key": "App", "Value": "newswires", @@ -612,80 +615,66 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Threshold": 0, + "Threshold": 10, "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "EXAMPLEfixedfrequencyLambdaHaywireAlarm739FFA93": { + "IngestionLambdaTESTC02B3E43": { + "DependsOn": [ + "IngestionLambdaTESTServiceRoleDefaultPolicy92C2CE04", + "IngestionLambdaTESTServiceRole62DE083D", + ], "Properties": { - "ActionsEnabled": true, - "AlarmActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], - }, + "Architectures": [ + "arm64", ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda has potentially gone haywire (has been invoked more frequently than expected).", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda_Haywire_Alarm", - "ComparisonOperator": "GreaterThanThreshold", - "Dimensions": [ - { - "Name": "FunctionName", - "Value": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda", + "Code": { + "S3Bucket": { + "Ref": "DistributionBucketName", }, - ], - "EvaluationPeriods": 1, - "MetricName": "Invocations", - "Namespace": "AWS/Lambda", - "OKActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, + "S3Key": "editorial-feeds/TEST/ingestion-lambda/ingestion-lambda.zip", + }, + "Environment": { + "Variables": { + "APP": "ingestion-lambda", + "DATABASE_ENDPOINT_ADDRESS": { + "Fn::GetAtt": [ + "NewswiresDBNewswires2A5A9AC6", + "Endpoint.Address", ], - ], + }, + "DATABASE_NAME": "newswires", + "DATABASE_PORT": { + "Fn::GetAtt": [ + "NewswiresDBNewswires2A5A9AC6", + "Endpoint.Port", + ], + }, + "FEEDS_BUCKET_NAME": { + "Ref": "feedsbucketTESTNewswires116BDB0E", + }, + "STACK": "editorial-feeds", + "STAGE": "TEST", }, - ], - "Period": 300, - "Statistic": "Sum", + }, + "Handler": "handler.main", + "LoggingConfig": { + "LogFormat": "JSON", + }, + "MemorySize": 512, + "ReservedConcurrentExecutions": 10, + "Role": { + "Fn::GetAtt": [ + "IngestionLambdaTESTServiceRole62DE083D", + "Arn", + ], + }, + "Runtime": "nodejs20.x", "Tags": [ { "Key": "App", - "Value": "newswires", + "Value": "ingestion-lambda", }, { "Key": "gu:cdk:version", @@ -704,20 +693,37 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Threshold": 15, - "TreatMissingData": "notBreaching", + "Timeout": 30, + "VpcConfig": { + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "IngestionLambdaTESTSecurityGroup5E6CBDBD", + "GroupId", + ], + }, + ], + "SubnetIds": { + "Ref": "newswiresPrivateSubnets", + }, + }, }, - "Type": "AWS::CloudWatch::Alarm", + "Type": "AWS::Lambda::Function", }, - "EXAMPLEfixedfrequencyLambdaQueueF55F5480": { - "DeletionPolicy": "Delete", + "IngestionLambdaTESTSecurityGroup5E6CBDBD": { "Properties": { - "MessageRetentionPeriod": 300, - "QueueName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda_queue", + "GroupDescription": "Automatic security group for Lambda Function NewswiresIngestionLambdaTESTD558924B", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1", + }, + ], "Tags": [ { "Key": "App", - "Value": "newswires", + "Value": "ingestion-lambda", }, { "Key": "gu:cdk:version", @@ -736,12 +742,13 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "VisibilityTimeout": 60, + "VpcId": { + "Ref": "VpcId", + }, }, - "Type": "AWS::SQS::Queue", - "UpdateReplacePolicy": "Delete", + "Type": "AWS::EC2::SecurityGroup", }, - "EXAMPLEfixedfrequencyLambdaServiceRoleBA2F232F": { + "IngestionLambdaTESTServiceRole62DE083D": { "Properties": { "AssumeRolePolicyDocument": { "Statement": [ @@ -768,11 +775,23 @@ exports[`The Newswires stack matches the snapshot 1`] = ` ], ], }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole", + ], + ], + }, ], "Tags": [ { "Key": "App", - "Value": "EXAMPLE_fixed_frequency_poller_lambda", + "Value": "ingestion-lambda", }, { "Key": "gu:cdk:version", @@ -794,7 +813,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` }, "Type": "AWS::IAM::Role", }, - "EXAMPLEfixedfrequencyLambdaServiceRoleDefaultPolicy272A9D10": { + "IngestionLambdaTESTServiceRoleDefaultPolicy92C2CE04": { "Properties": { "PolicyDocument": { "Statement": [ @@ -833,7 +852,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "DistributionBucketName", }, - "/editorial-feeds/TEST/EXAMPLE_fixed_frequency_poller_lambda/poller-lambdas.zip", + "/editorial-feeds/TEST/ingestion-lambda/ingestion-lambda.zip", ], ], }, @@ -854,7 +873,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/editorial-feeds/EXAMPLE_fixed_frequency_poller_lambda", + ":parameter/TEST/editorial-feeds/ingestion-lambda", ], ], }, @@ -877,21 +896,11 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/editorial-feeds/EXAMPLE_fixed_frequency_poller_lambda/*", + ":parameter/TEST/editorial-feeds/ingestion-lambda/*", ], ], }, }, - { - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret", - ], - "Effect": "Allow", - "Resource": { - "Ref": "EXAMPLEfixedfrequencySecretCB2DCB8C", - }, - }, { "Action": [ "sqs:ReceiveMessage", @@ -902,129 +911,146 @@ exports[`The Newswires stack matches the snapshot 1`] = ` ], "Effect": "Allow", "Resource": { - "Fn::GetAtt": [ - "EXAMPLEfixedfrequencyLambdaQueueF55F5480", - "Arn", - ], + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", }, }, { "Action": [ - "sqs:SendMessage", - "sqs:GetQueueAttributes", + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", "sqs:GetQueueUrl", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes", ], "Effect": "Allow", "Resource": { - "Fn::GetAtt": [ - "EXAMPLEfixedfrequencyLambdaQueueF55F5480", - "Arn", - ], + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockFingerpostQueue05E3D7ECArnA85146B3", }, }, { "Action": [ - "sqs:SendMessage", - "sqs:GetQueueAttributes", - "sqs:GetQueueUrl", + "s3:DeleteObject*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging", + "s3:Abort*", ], "Effect": "Allow", - "Resource": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", - }, - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "EXAMPLEfixedfrequencyLambdaServiceRoleDefaultPolicy272A9D10", - "Roles": [ - { - "Ref": "EXAMPLEfixedfrequencyLambdaServiceRoleBA2F232F", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, - "EXAMPLEfixedfrequencyLambdaSqsEventSourceNewswiresEXAMPLEfixedfrequencyLambdaQueue19E585D8ADCAD8C9": { - "Properties": { - "BatchSize": 1, - "EventSourceArn": { - "Fn::GetAtt": [ - "EXAMPLEfixedfrequencyLambdaQueueF55F5480", - "Arn", - ], - }, - "FunctionName": { - "Ref": "EXAMPLEfixedfrequencyLambdaD9A07041", - }, - }, - "Type": "AWS::Lambda::EventSourceMapping", - }, - "EXAMPLEfixedfrequencyLambdaStalledAlarm3E1E3005": { - "Properties": { - "ActionsEnabled": true, - "AlarmActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", + "Resource": [ { - "Ref": "AWS::Region", + "Fn::GetAtt": [ + "feedsbucketTESTNewswires116BDB0E", + "Arn", + ], }, - ":", { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "feedsbucketTESTNewswires116BDB0E", + "Arn", + ], + }, + "/*", + ], ], }, ], - ], - }, - ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda is potentially stalled (hasn't been invoked as frequently as expected).", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda_Stalled_Alarm", - "ComparisonOperator": "LessThanThreshold", - "Dimensions": [ + }, + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":rds-db:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":dbuser:", + { + "Fn::GetAtt": [ + "NewswiresDBNewswires2A5A9AC6", + "DbiResourceId", + ], + }, + "/{{resolve:secretsmanager:", + { + "Ref": "NewswiresDBNewswiresSecretCF4DBD56", + }, + ":SecretString:username::}}", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "IngestionLambdaTESTServiceRoleDefaultPolicy92C2CE04", + "Roles": [ { - "Name": "FunctionName", - "Value": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda", + "Ref": "IngestionLambdaTESTServiceRole62DE083D", }, ], - "EvaluationPeriods": 1, - "MetricName": "Invocations", - "Namespace": "AWS/Lambda", - "OKActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], - }, + }, + "Type": "AWS::IAM::Policy", + }, + "IngestionLambdaTESTSqsEventSourcemockWiresFeedsMockFingerpostQueue19AE08DA454EF2E1": { + "Properties": { + "EventSourceArn": { + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockFingerpostQueue05E3D7ECArnA85146B3", + }, + "FunctionName": { + "Ref": "IngestionLambdaTESTC02B3E43", + }, + "FunctionResponseTypes": [ + "ReportBatchItemFailures", ], - "Period": 900, - "Statistic": "Sum", + }, + "Type": "AWS::Lambda::EventSourceMapping", + }, + "IngestionLambdaTESTSqsEventSourcemockWiresFeedsMockSourceQueue17F9CFF698B624D6": { + "Properties": { + "EventSourceArn": { + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", + }, + "FunctionName": { + "Ref": "IngestionLambdaTESTC02B3E43", + }, + "FunctionResponseTypes": [ + "ReportBatchItemFailures", + ], + }, + "Type": "AWS::Lambda::EventSourceMapping", + }, + "InstanceRoleNewswiresC10A0615": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + "Path": "/", "Tags": [ { "Key": "App", @@ -1047,84 +1073,120 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Threshold": 30, - "TreatMissingData": "breaching", }, - "Type": "AWS::CloudWatch::Alarm", + "Type": "AWS::IAM::Role", }, - "EXAMPLEfixedfrequencyLambdaThrottlingAlarmForLambda7B722356": { + "InstanceRoleNewswiresDefaultPolicyA474C079": { "Properties": { - "ActionsEnabled": true, - "AlarmActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", + "PolicyDocument": { + "Statement": [ + { + "Action": "rds-db:connect", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":rds-db:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":dbuser:", + { + "Fn::GetAtt": [ + "NewswiresDBNewswires2A5A9AC6", + "DbiResourceId", + ], + }, + "/{{resolve:secretsmanager:", + { + "Ref": "NewswiresDBNewswiresSecretCF4DBD56", + }, + ":SecretString:username::}}", ], - }, - ], - ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "InstanceRoleNewswiresDefaultPolicyA474C079", + "Roles": [ + { + "Ref": "InstanceRoleNewswiresC10A0615", }, ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda is throttling.", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_fixed_frequency_poller_lambda_Throttling_Alarm", - "ComparisonOperator": "GreaterThanThreshold", - "Dimensions": [ + }, + "Type": "AWS::IAM::Policy", + }, + "ListenerNewswires227C913D": { + "Properties": { + "Certificates": [ { - "Name": "FunctionName", - "Value": { - "Ref": "EXAMPLEfixedfrequencyLambdaD9A07041", + "CertificateArn": { + "Ref": "CertificateNewswiresFEA3DE56", }, }, ], - "EvaluationPeriods": 1, - "MetricName": "Throttles", - "Namespace": "AWS/Lambda", - "OKActions": [ + "DefaultActions": [ { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], + "TargetGroupArn": { + "Ref": "TargetGroupNewswires87809E8A", + }, + "Type": "forward", }, ], - "Period": 60, - "Statistic": "Sum", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { + "LoadBalancerArn": { + "Ref": "LoadBalancerNewswires3B8BBCB3", + }, + "Port": 443, + "Protocol": "HTTPS", + "SslPolicy": "ELBSecurityPolicy-TLS13-1-2-2021-06", + }, + "Type": "AWS::ElasticLoadBalancingV2::Listener", + }, + "LoadBalancerNewswires3B8BBCB3": { + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "true", + }, + { + "Key": "routing.http.x_amzn_tls_version_and_cipher_suite.enabled", + "Value": "true", + }, + { + "Key": "routing.http.drop_invalid_header_fields.enabled", + "Value": "true", + }, + ], + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "LoadBalancerNewswiresSecurityGroupF93D2107", + "GroupId", + ], + }, + ], + "Subnets": { + "Ref": "newswiresPublicSubnets", + }, + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { "Key": "gu:cdk:version", "Value": "TEST", }, @@ -1141,17 +1203,22 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Threshold": 0, - "TreatMissingData": "notBreaching", + "Type": "application", }, - "Type": "AWS::CloudWatch::Alarm", + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", }, - "EXAMPLEfixedfrequencySecretCB2DCB8C": { - "DeletionPolicy": "Delete", + "LoadBalancerNewswiresSecurityGroupF93D2107": { "Properties": { - "Description": "Secret for the EXAMPLE_fixed_frequency poller lambda", - "GenerateSecretString": {}, - "Name": "/TEST/editorial-feeds/newswires/EXAMPLE_fixed_frequency_poller_lambda", + "GroupDescription": "Automatically created Security Group for ELB NewswiresLoadBalancerNewswires55D111EE", + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 443", + "FromPort": 443, + "IpProtocol": "tcp", + "ToPort": 443, + }, + ], "Tags": [ { "Key": "App", @@ -1174,110 +1241,130 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], + "VpcId": { + "Ref": "VpcId", + }, }, - "Type": "AWS::SecretsManager::Secret", - "UpdateReplacePolicy": "Delete", + "Type": "AWS::EC2::SecurityGroup", }, - "EXAMPLElongpollingLambdaDC443D98": { - "DependsOn": [ - "EXAMPLElongpollingLambdaServiceRoleDefaultPolicy72E70E87", - "EXAMPLElongpollingLambdaServiceRoleF2C4DC08", - ], + "LoadBalancerNewswiresSecurityGrouptoNewswiresDefaultSecurityGroupNewswires40BF4E639000CA7B98AE": { "Properties": { - "Architectures": [ - "arm64", - ], - "Code": { - "S3Bucket": { - "Ref": "DistributionBucketName", - }, - "S3Key": "editorial-feeds/TEST/EXAMPLE_long_polling_poller_lambda/poller-lambdas.zip", + "Description": "Load balancer to target", + "DestinationSecurityGroupId": { + "Fn::GetAtt": [ + "DefaultSecurityGroupNewswires91CCC0BF", + "GroupId", + ], }, - "Environment": { - "Variables": { - "APP": "EXAMPLE_long_polling_poller_lambda", - "INGESTION_LAMBDA_QUEUE_URL": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputRefMockSourceQueue20B4D8C006FBA8DA", - }, - "OWN_QUEUE_URL": { - "Ref": "EXAMPLElongpollingLambdaQueue0E2C8DED", - }, - "SECRET_NAME": { - "Fn::Join": [ - "-", - [ - { - "Fn::Select": [ - 0, - { - "Fn::Split": [ - "-", - { - "Fn::Select": [ - 6, - { - "Fn::Split": [ - ":", - { - "Ref": "EXAMPLElongpollingSecret702B1E98", - }, - ], - }, - ], - }, - ], - }, - ], - }, - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - "-", - { - "Fn::Select": [ - 6, - { - "Fn::Split": [ - ":", - { - "Ref": "EXAMPLElongpollingSecret702B1E98", - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - ], - }, - "STACK": "editorial-feeds", - "STAGE": "TEST", - }, + "FromPort": 9000, + "GroupId": { + "Fn::GetAtt": [ + "LoadBalancerNewswiresSecurityGroupF93D2107", + "GroupId", + ], }, - "FunctionName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda", - "Handler": "index.handlers.EXAMPLE_long_polling", - "LoggingConfig": { - "LogFormat": "JSON", + "IpProtocol": "tcp", + "ToPort": 9000, + }, + "Type": "AWS::EC2::SecurityGroupEgress", + }, + "LoadBalancerNewswiresSecurityGrouptoNewswiresGuHttpsEgressSecurityGroupNewswires371358559000483685BB": { + "Properties": { + "Description": "Load balancer to target", + "DestinationSecurityGroupId": { + "Fn::GetAtt": [ + "GuHttpsEgressSecurityGroupNewswiresEF9436B0", + "GroupId", + ], }, - "MemorySize": 128, - "RecursiveLoop": "Allow", - "ReservedConcurrentExecutions": 2, - "Role": { + "FromPort": 9000, + "GroupId": { "Fn::GetAtt": [ - "EXAMPLElongpollingLambdaServiceRoleF2C4DC08", - "Arn", + "LoadBalancerNewswiresSecurityGroupF93D2107", + "GroupId", ], }, - "Runtime": "nodejs20.x", + "IpProtocol": "tcp", + "ToPort": 9000, + }, + "Type": "AWS::EC2::SecurityGroupEgress", + }, + "LoadBalancerNewswiresSecurityGrouptoNewswiresWazuhSecurityGroupCCE261159000C5B90044": { + "Properties": { + "Description": "Load balancer to target", + "DestinationSecurityGroupId": { + "Fn::GetAtt": [ + "WazuhSecurityGroup", + "GroupId", + ], + }, + "FromPort": 9000, + "GroupId": { + "Fn::GetAtt": [ + "LoadBalancerNewswiresSecurityGroupF93D2107", + "GroupId", + ], + }, + "IpProtocol": "tcp", + "ToPort": 9000, + }, + "Type": "AWS::EC2::SecurityGroupEgress", + }, + "NewswiresDBNewswires2A5A9AC6": { + "DeletionPolicy": "Snapshot", + "Properties": { + "AllocatedStorage": "100", + "AutoMinorVersionUpgrade": false, + "CACertificateIdentifier": "rds-ca-rsa2048-g1", + "CopyTagsToSnapshot": true, + "DBInstanceClass": "db.t4g.small", + "DBName": "newswires", + "DBSubnetGroupName": { + "Ref": "NewswiresDBNewswiresSubnetGroupC2336A30", + }, + "DeletionProtection": true, + "EnableIAMDatabaseAuthentication": true, + "Engine": "postgres", + "EngineVersion": "16.4", + "Iops": 3000, + "MasterUserPassword": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "NewswiresDBNewswiresSecretCF4DBD56", + }, + ":SecretString:password::}}", + ], + ], + }, + "MasterUsername": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:", + { + "Ref": "NewswiresDBNewswiresSecretCF4DBD56", + }, + ":SecretString:username::}}", + ], + ], + }, + "MultiAZ": false, + "Port": "5432", + "PubliclyAccessible": false, + "StorageEncrypted": true, + "StorageThroughput": 125, + "StorageType": "gp3", "Tags": [ { "Key": "App", - "Value": "EXAMPLE_long_polling_poller_lambda", + "Value": "newswires", + }, + { + "Key": "devx-backup-enabled", + "Value": "true", }, { "Key": "gu:cdk:version", @@ -1296,122 +1383,165 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Timeout": 60, - }, - "Type": "AWS::Lambda::Function", - }, - "EXAMPLElongpollingLambdaErrorPercentageAlarmForLambda3358F222": { - "Properties": { - "ActionsEnabled": true, - "AlarmActions": [ + "VPCSecurityGroups": [ { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], + "Fn::GetAtt": [ + "DefaultSecurityGroupNewswires91CCC0BF", + "GroupId", ], }, ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda is erroring.", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda_Error_Alarm", - "ComparisonOperator": "GreaterThanThreshold", - "EvaluationPeriods": 1, - "Metrics": [ + }, + "Type": "AWS::RDS::DBInstance", + "UpdateReplacePolicy": "Snapshot", + }, + "NewswiresDBNewswiresAccessSecurityGroupParamEEED45CA": { + "Properties": { + "DataType": "text", + "Name": "/TEST/editorial-feeds/newswires/database/access-security-group", + "Tags": { + "App": "newswires", + "Stack": "editorial-feeds", + "Stage": "TEST", + "gu:cdk:version": "TEST", + "gu:repo": "guardian/newswires", + }, + "Tier": "Standard", + "Type": "String", + "Value": { + "Fn::GetAtt": [ + "DefaultSecurityGroupNewswires91CCC0BF", + "GroupId", + ], + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "NewswiresDBNewswiresDatabaseNameParam46DC31AD": { + "Properties": { + "DataType": "text", + "Name": "/TEST/editorial-feeds/newswires/database/database-name", + "Tags": { + "App": "newswires", + "Stack": "editorial-feeds", + "Stage": "TEST", + "gu:cdk:version": "TEST", + "gu:repo": "guardian/newswires", + }, + "Tier": "Standard", + "Type": "String", + "Value": "newswires", + }, + "Type": "AWS::SSM::Parameter", + }, + "NewswiresDBNewswiresEndpointAddressParam62BDC1A2": { + "Properties": { + "DataType": "text", + "Name": "/TEST/editorial-feeds/newswires/database/endpoint-address", + "Tags": { + "App": "newswires", + "Stack": "editorial-feeds", + "Stage": "TEST", + "gu:cdk:version": "TEST", + "gu:repo": "guardian/newswires", + }, + "Tier": "Standard", + "Type": "String", + "Value": { + "Fn::GetAtt": [ + "NewswiresDBNewswires2A5A9AC6", + "Endpoint.Address", + ], + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "NewswiresDBNewswiresPortParam6F050C46": { + "Properties": { + "DataType": "text", + "Name": "/TEST/editorial-feeds/newswires/database/port", + "Tags": { + "App": "newswires", + "Stack": "editorial-feeds", + "Stage": "TEST", + "gu:cdk:version": "TEST", + "gu:repo": "guardian/newswires", + }, + "Tier": "Standard", + "Type": "String", + "Value": { + "Fn::GetAtt": [ + "NewswiresDBNewswires2A5A9AC6", + "Endpoint.Port", + ], + }, + }, + "Type": "AWS::SSM::Parameter", + }, + "NewswiresDBNewswiresSecretAttachment35EF265F": { + "Properties": { + "SecretId": { + "Ref": "NewswiresDBNewswiresSecretCF4DBD56", + }, + "TargetId": { + "Ref": "NewswiresDBNewswires2A5A9AC6", + }, + "TargetType": "AWS::RDS::DBInstance", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "NewswiresDBNewswiresSecretCF4DBD56": { + "DeletionPolicy": "Delete", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"postgres"}", + }, + "Tags": [ { - "Expression": "100*m1/m2", - "Id": "expr_1", - "Label": { - "Fn::Join": [ - "", - [ - "Error % of ", - { - "Ref": "EXAMPLElongpollingLambdaDC443D98", - }, - ], - ], - }, + "Key": "App", + "Value": "newswires", }, { - "Id": "m1", - "MetricStat": { - "Metric": { - "Dimensions": [ - { - "Name": "FunctionName", - "Value": { - "Ref": "EXAMPLElongpollingLambdaDC443D98", - }, - }, - ], - "MetricName": "Errors", - "Namespace": "AWS/Lambda", - }, - "Period": 60, - "Stat": "Sum", - }, - "ReturnData": false, + "Key": "gu:cdk:version", + "Value": "TEST", }, { - "Id": "m2", - "MetricStat": { - "Metric": { - "Dimensions": [ - { - "Name": "FunctionName", - "Value": { - "Ref": "EXAMPLElongpollingLambdaDC443D98", - }, - }, - ], - "MetricName": "Invocations", - "Namespace": "AWS/Lambda", - }, - "Period": 60, - "Stat": "Sum", - }, - "ReturnData": false, + "Key": "gu:repo", + "Value": "guardian/newswires", }, - ], - "OKActions": [ { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", }, ], + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "NewswiresDBNewswiresSubnetGroupC2336A30": { + "Properties": { + "DBSubnetGroupDescription": "Subnet group for NewswiresDBNewswires database", + "SubnetIds": { + "Ref": "newswiresPrivateSubnets", + }, "Tags": [ { "Key": "App", @@ -1434,180 +1564,62 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Threshold": 0, - "TreatMissingData": "notBreaching", }, - "Type": "AWS::CloudWatch::Alarm", + "Type": "AWS::RDS::DBSubnetGroup", }, - "EXAMPLElongpollingLambdaHaywireAlarmFB9A2851": { + "NewswiresDBNewswiresUsernameParam880243B7": { "Properties": { - "ActionsEnabled": true, - "AlarmActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], - }, - ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda has potentially gone haywire (has been invoked more frequently than expected).", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda_Haywire_Alarm", - "ComparisonOperator": "GreaterThanThreshold", - "Dimensions": [ - { - "Name": "FunctionName", - "Value": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda", - }, - ], - "EvaluationPeriods": 1, - "MetricName": "Invocations", - "Namespace": "AWS/Lambda", - "OKActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], - }, - ], - "Period": 60, - "Statistic": "Sum", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "Threshold": 60, - "TreatMissingData": "notBreaching", + "DataType": "text", + "Name": "/TEST/editorial-feeds/newswires/database/username", + "Tags": { + "App": "newswires", + "Stack": "editorial-feeds", + "Stage": "TEST", + "gu:cdk:version": "TEST", + "gu:repo": "guardian/newswires", + }, + "Tier": "Standard", + "Type": "String", + "Value": "postgres", }, - "Type": "AWS::CloudWatch::Alarm", + "Type": "AWS::SSM::Parameter", }, - "EXAMPLElongpollingLambdaQueue0E2C8DED": { - "DeletionPolicy": "Delete", + "PandaAuthPolicy4E029301": { "Properties": { - "MessageRetentionPeriod": 300, - "QueueName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda_queue", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:GetObject", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "PanDomainSettingsBucket", + }, + "/*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "PandaAuthPolicy4E029301", + "Roles": [ { - "Key": "Stage", - "Value": "TEST", + "Ref": "InstanceRoleNewswiresC10A0615", }, ], - "VisibilityTimeout": 60, }, - "Type": "AWS::SQS::Queue", - "UpdateReplacePolicy": "Delete", + "Type": "AWS::IAM::Policy", }, - "EXAMPLElongpollingLambdaServiceRoleDefaultPolicy72E70E87": { + "ParameterStoreReadNewswiresF3917A8D": { "Properties": { "PolicyDocument": { "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*", - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":s3:::", - { - "Ref": "DistributionBucketName", - }, - ], - ], - }, - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":s3:::", - { - "Ref": "DistributionBucketName", - }, - "/editorial-feeds/TEST/EXAMPLE_long_polling_poller_lambda/poller-lambdas.zip", - ], - ], - }, - ], - }, { "Action": "ssm:GetParametersByPath", "Effect": "Allow", @@ -1623,7 +1635,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/editorial-feeds/EXAMPLE_long_polling_poller_lambda", + ":parameter/TEST/editorial-feeds/newswires", ], ], }, @@ -1646,106 +1658,104 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/editorial-feeds/EXAMPLE_long_polling_poller_lambda/*", + ":parameter/TEST/editorial-feeds/newswires/*", ], ], }, }, - { - "Action": [ - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret", - ], - "Effect": "Allow", - "Resource": { - "Ref": "EXAMPLElongpollingSecret702B1E98", - }, - }, - { - "Action": [ - "sqs:ReceiveMessage", - "sqs:ChangeMessageVisibility", - "sqs:GetQueueUrl", - "sqs:DeleteMessage", - "sqs:GetQueueAttributes", - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "EXAMPLElongpollingLambdaQueue0E2C8DED", - "Arn", - ], - }, - }, - { - "Action": [ - "sqs:SendMessage", - "sqs:GetQueueAttributes", - "sqs:GetQueueUrl", - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "EXAMPLElongpollingLambdaQueue0E2C8DED", - "Arn", - ], - }, - }, - { - "Action": [ - "sqs:SendMessage", - "sqs:GetQueueAttributes", - "sqs:GetQueueUrl", - ], - "Effect": "Allow", - "Resource": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", - }, - }, ], "Version": "2012-10-17", }, - "PolicyName": "EXAMPLElongpollingLambdaServiceRoleDefaultPolicy72E70E87", + "PolicyName": "parameter-store-read-policy", "Roles": [ { - "Ref": "EXAMPLElongpollingLambdaServiceRoleF2C4DC08", + "Ref": "InstanceRoleNewswiresC10A0615", }, ], }, "Type": "AWS::IAM::Policy", }, - "EXAMPLElongpollingLambdaServiceRoleF2C4DC08": { + "PermissionsCachePolicyEB49F1A4": { "Properties": { - "AssumeRolePolicyDocument": { + "PolicyDocument": { "Statement": [ { - "Action": "sts:AssumeRole", + "Action": "s3:GetObject", "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "PermissionsBucket", + }, + "/TEST/*", + ], + ], }, }, ], "Version": "2012-10-17", }, - "ManagedPolicyArns": [ + "PolicyName": "PermissionsCachePolicyEB49F1A4", + "Roles": [ { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "Ref": "InstanceRoleNewswiresC10A0615", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "SsmSshPolicy4CFC977E": { + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ec2messages:AcknowledgeMessage", + "ec2messages:DeleteMessage", + "ec2messages:FailMessage", + "ec2messages:GetEndpoint", + "ec2messages:GetMessages", + "ec2messages:SendReply", + "ssm:UpdateInstanceInformation", + "ssm:ListInstanceAssociations", + "ssm:DescribeInstanceProperties", + "ssm:DescribeDocumentParameters", + "ssmmessages:CreateControlChannel", + "ssmmessages:CreateDataChannel", + "ssmmessages:OpenControlChannel", + "ssmmessages:OpenDataChannel", ], - ], + "Effect": "Allow", + "Resource": "*", + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "ssm-ssh-policy", + "Roles": [ + { + "Ref": "InstanceRoleNewswiresC10A0615", }, ], + }, + "Type": "AWS::IAM::Policy", + }, + "TargetGroupNewswires87809E8A": { + "Properties": { + "HealthCheckIntervalSeconds": 10, + "HealthCheckPath": "/healthcheck", + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": 5, + "HealthyThresholdCount": 5, + "Port": 9000, + "Protocol": "HTTP", "Tags": [ { "Key": "App", - "Value": "EXAMPLE_long_polling_poller_lambda", + "Value": "newswires", }, { "Key": "gu:cdk:version", @@ -1764,25 +1774,25 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - }, - "Type": "AWS::IAM::Role", - }, - "EXAMPLElongpollingLambdaSqsEventSourceNewswiresEXAMPLElongpollingLambdaQueue7E62ACD815B2FCD9": { - "Properties": { - "BatchSize": 1, - "EventSourceArn": { - "Fn::GetAtt": [ - "EXAMPLElongpollingLambdaQueue0E2C8DED", - "Arn", - ], - }, - "FunctionName": { - "Ref": "EXAMPLElongpollingLambdaDC443D98", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "30", + }, + { + "Key": "stickiness.enabled", + "Value": "false", + }, + ], + "TargetType": "instance", + "UnhealthyThresholdCount": 2, + "VpcId": { + "Ref": "VpcId", }, }, - "Type": "AWS::Lambda::EventSourceMapping", + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", }, - "EXAMPLElongpollingLambdaStalledAlarm6F0BABB6": { + "UnhealthyInstancesAlarmNewswires7AAD87B6": { "Properties": { "ActionsEnabled": true, "AlarmActions": [ @@ -1809,44 +1819,81 @@ exports[`The Newswires stack matches the snapshot 1`] = ` ], }, ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda is potentially stalled (hasn't been invoked as frequently as expected).", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda_Stalled_Alarm", - "ComparisonOperator": "LessThanThreshold", + "AlarmDescription": "newswires's instances have failed healthchecks several times over the last 1 hour. + This typically results in the AutoScaling Group cycling instances and can lead to problems with deployment, + scaling or handling traffic spikes. + + Check newswires's application logs or ssh onto an unhealthy instance in order to debug these problems.", + "AlarmName": "Unhealthy instances for newswires in TEST", + "ComparisonOperator": "GreaterThanOrEqualToThreshold", + "DatapointsToAlarm": 30, "Dimensions": [ { - "Name": "FunctionName", - "Value": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda", + "Name": "LoadBalancer", + "Value": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "/", + { + "Ref": "ListenerNewswires227C913D", + }, + ], + }, + ], + }, + "/", + { + "Fn::Select": [ + 2, + { + "Fn::Split": [ + "/", + { + "Ref": "ListenerNewswires227C913D", + }, + ], + }, + ], + }, + "/", + { + "Fn::Select": [ + 3, + { + "Fn::Split": [ + "/", + { + "Ref": "ListenerNewswires227C913D", + }, + ], + }, + ], + }, + ], + ], + }, }, - ], - "EvaluationPeriods": 1, - "MetricName": "Invocations", - "Namespace": "AWS/Lambda", - "OKActions": [ { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, + "Name": "TargetGroup", + "Value": { + "Fn::GetAtt": [ + "TargetGroupNewswires87809E8A", + "TargetGroupFullName", ], - ], + }, }, ], - "Period": 180, - "Statistic": "Sum", + "EvaluationPeriods": 60, + "MetricName": "UnHealthyHostCount", + "Namespace": "AWS/ApplicationELB", + "Period": 60, + "Statistic": "Maximum", "Tags": [ { "Key": "App", @@ -1870,77 +1917,29 @@ exports[`The Newswires stack matches the snapshot 1`] = ` }, ], "Threshold": 1, - "TreatMissingData": "breaching", + "TreatMissingData": "notBreaching", }, "Type": "AWS::CloudWatch::Alarm", }, - "EXAMPLElongpollingLambdaThrottlingAlarmForLambda289EA080": { + "WazuhSecurityGroup": { "Properties": { - "ActionsEnabled": true, - "AlarmActions": [ - { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], - }, - ], - "AlarmDescription": "The editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda is throttling.", - "AlarmName": "editorial-feeds-TEST-EXAMPLE_long_polling_poller_lambda_Throttling_Alarm", - "ComparisonOperator": "GreaterThanThreshold", - "Dimensions": [ + "GroupDescription": "Allow outbound traffic from wazuh agent to manager", + "SecurityGroupEgress": [ { - "Name": "FunctionName", - "Value": { - "Ref": "EXAMPLElongpollingLambdaDC443D98", - }, + "CidrIp": "0.0.0.0/0", + "Description": "Wazuh event logging", + "FromPort": 1514, + "IpProtocol": "tcp", + "ToPort": 1514, }, - ], - "EvaluationPeriods": 1, - "MetricName": "Throttles", - "Namespace": "AWS/Lambda", - "OKActions": [ { - "Fn::Join": [ - "", - [ - "arn:aws:sns:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":", - { - "Fn::GetAtt": [ - "newswiresemailalarmtopicB2906D97", - "TopicName", - ], - }, - ], - ], + "CidrIp": "0.0.0.0/0", + "Description": "Wazuh agent registration", + "FromPort": 1515, + "IpProtocol": "tcp", + "ToPort": 1515, }, ], - "Period": 60, - "Statistic": "Sum", "Tags": [ { "Key": "App", @@ -1963,17 +1962,207 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "Threshold": 0, - "TreatMissingData": "notBreaching", + "VpcId": { + "Ref": "VpcId", + }, }, - "Type": "AWS::CloudWatch::Alarm", + "Type": "AWS::EC2::SecurityGroup", }, - "EXAMPLElongpollingSecret702B1E98": { - "DeletionPolicy": "Delete", + "WazuhSecurityGroupfromNewswiresLoadBalancerNewswiresSecurityGroup255ABDD190009D3830D6": { "Properties": { - "Description": "Secret for the EXAMPLE_long_polling poller lambda", - "GenerateSecretString": {}, - "Name": "/TEST/editorial-feeds/newswires/EXAMPLE_long_polling_poller_lambda", + "Description": "Load balancer to target", + "FromPort": 9000, + "GroupId": { + "Fn::GetAtt": [ + "WazuhSecurityGroup", + "GroupId", + ], + }, + "IpProtocol": "tcp", + "SourceSecurityGroupId": { + "Fn::GetAtt": [ + "LoadBalancerNewswiresSecurityGroupF93D2107", + "GroupId", + ], + }, + "ToPort": 9000, + }, + "Type": "AWS::EC2::SecurityGroupIngress", + }, + "editorialfeedsTESTnewswires01BC2EBA": { + "DependsOn": [ + "InstanceRoleNewswiresDefaultPolicyA474C079", + "InstanceRoleNewswiresC10A0615", + ], + "Properties": { + "LaunchTemplateData": { + "IamInstanceProfile": { + "Arn": { + "Fn::GetAtt": [ + "editorialfeedsTESTnewswiresProfileD57DD674", + "Arn", + ], + }, + }, + "ImageId": { + "Ref": "AMINewswires", + }, + "InstanceType": "t4g.small", + "MetadataOptions": { + "HttpTokens": "required", + "InstanceMetadataTags": "enabled", + }, + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "GuHttpsEgressSecurityGroupNewswiresEF9436B0", + "GroupId", + ], + }, + { + "Fn::GetAtt": [ + "WazuhSecurityGroup", + "GroupId", + ], + }, + { + "Fn::GetAtt": [ + "DefaultSecurityGroupNewswires91CCC0BF", + "GroupId", + ], + }, + ], + "TagSpecifications": [ + { + "ResourceType": "instance", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Name", + "Value": "Newswires/editorial-feeds-TEST-newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + { + "ResourceType": "volume", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Name", + "Value": "Newswires/editorial-feeds-TEST-newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + ], + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", + [ + "#!/bin/bash +mkdir -p $(dirname '/newswires/newswires.deb') +aws s3 cp 's3://", + { + "Ref": "DistributionBucketName", + }, + "/editorial-feeds/TEST/newswires/newswires.deb' '/newswires/newswires.deb' +dpkg -i /newswires/newswires.deb", + ], + ], + }, + }, + }, + "TagSpecifications": [ + { + "ResourceType": "launch-template", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Name", + "Value": "Newswires/editorial-feeds-TEST-newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + ], + }, + "Type": "AWS::EC2::LaunchTemplate", + }, + "editorialfeedsTESTnewswiresProfileD57DD674": { + "Properties": { + "Roles": [ + { + "Ref": "InstanceRoleNewswiresC10A0615", + }, + ], + }, + "Type": "AWS::IAM::InstanceProfile", + }, + "feedsbucketTESTNewswires116BDB0E": { + "DeletionPolicy": "Retain", + "Properties": { + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true, + }, "Tags": [ { "Key": "App", @@ -1996,54 +2185,15 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - }, - "Type": "AWS::SecretsManager::Secret", - "UpdateReplacePolicy": "Delete", - }, - "GetDistributablePolicyNewswires3D555C70": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "s3:GetObject", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:aws:s3:::", - { - "Ref": "DistributionBucketName", - }, - "/editorial-feeds/TEST/newswires/*", - ], - ], - }, - }, - ], - "Version": "2012-10-17", + "VersioningConfiguration": { + "Status": "Enabled", }, - "PolicyName": "GetDistributablePolicyNewswires3D555C70", - "Roles": [ - { - "Ref": "InstanceRoleNewswiresC10A0615", - }, - ], }, - "Type": "AWS::IAM::Policy", + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Retain", }, - "GuHttpsEgressSecurityGroupNewswiresEF9436B0": { + "newswiresemailalarmtopicB2906D97": { "Properties": { - "GroupDescription": "Allow all outbound HTTPS traffic", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound HTTPS traffic", - "FromPort": 443, - "IpProtocol": "tcp", - "ToPort": 443, - }, - ], "Tags": [ { "Key": "App", @@ -2066,76 +2216,132 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "VpcId": { - "Ref": "VpcId", - }, }, - "Type": "AWS::EC2::SecurityGroup", + "Type": "AWS::SNS::Topic", }, - "GuHttpsEgressSecurityGroupNewswiresfromNewswiresLoadBalancerNewswiresSecurityGroup255ABDD190005C31A09F": { + "reutersLambda21FE513B": { + "DependsOn": [ + "reutersLambdaServiceRoleDefaultPolicy86486920", + "reutersLambdaServiceRoleB1396562", + ], "Properties": { - "Description": "Load balancer to target", - "FromPort": 9000, - "GroupId": { - "Fn::GetAtt": [ - "GuHttpsEgressSecurityGroupNewswiresEF9436B0", - "GroupId", - ], - }, - "IpProtocol": "tcp", - "SourceSecurityGroupId": { - "Fn::GetAtt": [ - "LoadBalancerNewswiresSecurityGroupF93D2107", - "GroupId", - ], + "Architectures": [ + "arm64", + ], + "Code": { + "S3Bucket": { + "Ref": "DistributionBucketName", + }, + "S3Key": "editorial-feeds/TEST/reuters_poller_lambda/poller-lambdas.zip", }, - "ToPort": 9000, - }, - "Type": "AWS::EC2::SecurityGroupIngress", - }, - "GuLogShippingPolicy981BFE5A": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "kinesis:Describe*", - "kinesis:Put*", - ], - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:aws:kinesis:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":stream/", - { - "Ref": "LoggingStreamName", - }, - ], + "Environment": { + "Variables": { + "APP": "reuters_poller_lambda", + "INGESTION_LAMBDA_QUEUE_URL": { + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputRefMockSourceQueue20B4D8C006FBA8DA", + }, + "OWN_QUEUE_URL": { + "Ref": "reutersLambdaQueue7636161A", + }, + "SECRET_NAME": { + "Fn::Join": [ + "-", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "-", + { + "Fn::Select": [ + 6, + { + "Fn::Split": [ + ":", + { + "Ref": "reutersSecretA9E37489", + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "-", + { + "Fn::Select": [ + 6, + { + "Fn::Split": [ + ":", + { + "Ref": "reutersSecretA9E37489", + }, + ], + }, + ], + }, + ], + }, + ], + }, ], - }, + ], }, + "STACK": "editorial-feeds", + "STAGE": "TEST", + }, + }, + "FunctionName": "editorial-feeds-TEST-reuters_poller_lambda", + "Handler": "index.handlers.reuters", + "LoggingConfig": { + "LogFormat": "JSON", + }, + "MemorySize": 128, + "RecursiveLoop": "Allow", + "ReservedConcurrentExecutions": 2, + "Role": { + "Fn::GetAtt": [ + "reutersLambdaServiceRoleB1396562", + "Arn", ], - "Version": "2012-10-17", }, - "PolicyName": "GuLogShippingPolicy981BFE5A", - "Roles": [ + "Runtime": "nodejs20.x", + "Tags": [ { - "Ref": "InstanceRoleNewswiresC10A0615", + "Key": "App", + "Value": "reuters_poller_lambda", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", }, ], + "Timeout": 60, }, - "Type": "AWS::IAM::Policy", + "Type": "AWS::Lambda::Function", }, - "High5xxPercentageAlarmNewswiresC0FCCFC5": { + "reutersLambdaErrorPercentageAlarmForLambdaA449406D": { "Properties": { "ActionsEnabled": true, "AlarmActions": [ @@ -2162,56 +2368,40 @@ exports[`The Newswires stack matches the snapshot 1`] = ` ], }, ], - "AlarmDescription": "newswires exceeded 10% error rate", - "AlarmName": "High 5XX error percentage from newswires in TEST", + "AlarmDescription": "The editorial-feeds-TEST-reuters_poller_lambda is erroring.", + "AlarmName": "editorial-feeds-TEST-reuters_poller_lambda_Error_Alarm", "ComparisonOperator": "GreaterThanThreshold", "EvaluationPeriods": 1, "Metrics": [ { - "Expression": "100*(m1+m2)/m3", + "Expression": "100*m1/m2", "Id": "expr_1", - "Label": "% of 5XX responses served for newswires (load balancer and instances combined)", - }, - { - "Id": "m1", - "MetricStat": { - "Metric": { - "Dimensions": [ + "Label": { + "Fn::Join": [ + "", + [ + "Error % of ", { - "Name": "LoadBalancer", - "Value": { - "Fn::GetAtt": [ - "LoadBalancerNewswires3B8BBCB3", - "LoadBalancerFullName", - ], - }, + "Ref": "reutersLambda21FE513B", }, ], - "MetricName": "HTTPCode_ELB_5XX_Count", - "Namespace": "AWS/ApplicationELB", - }, - "Period": 60, - "Stat": "Sum", + ], }, - "ReturnData": false, }, { - "Id": "m2", + "Id": "m1", "MetricStat": { "Metric": { "Dimensions": [ { - "Name": "LoadBalancer", + "Name": "FunctionName", "Value": { - "Fn::GetAtt": [ - "LoadBalancerNewswires3B8BBCB3", - "LoadBalancerFullName", - ], + "Ref": "reutersLambda21FE513B", }, }, ], - "MetricName": "HTTPCode_Target_5XX_Count", - "Namespace": "AWS/ApplicationELB", + "MetricName": "Errors", + "Namespace": "AWS/Lambda", }, "Period": 60, "Stat": "Sum", @@ -2219,22 +2409,19 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "ReturnData": false, }, { - "Id": "m3", + "Id": "m2", "MetricStat": { "Metric": { "Dimensions": [ { - "Name": "LoadBalancer", + "Name": "FunctionName", "Value": { - "Fn::GetAtt": [ - "LoadBalancerNewswires3B8BBCB3", - "LoadBalancerFullName", - ], + "Ref": "reutersLambda21FE513B", }, }, ], - "MetricName": "RequestCount", - "Namespace": "AWS/ApplicationELB", + "MetricName": "Invocations", + "Namespace": "AWS/Lambda", }, "Period": 60, "Stat": "Sum", @@ -2242,923 +2429,30 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "ReturnData": false, }, ], - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "Threshold": 10, - "TreatMissingData": "notBreaching", - }, - "Type": "AWS::CloudWatch::Alarm", - }, - "IngestionLambdaTESTC02B3E43": { - "DependsOn": [ - "IngestionLambdaTESTServiceRoleDefaultPolicy92C2CE04", - "IngestionLambdaTESTServiceRole62DE083D", - ], - "Properties": { - "Architectures": [ - "arm64", - ], - "Code": { - "S3Bucket": { - "Ref": "DistributionBucketName", - }, - "S3Key": "editorial-feeds/TEST/ingestion-lambda/ingestion-lambda.zip", - }, - "Environment": { - "Variables": { - "APP": "ingestion-lambda", - "DATABASE_ENDPOINT_ADDRESS": { - "Fn::GetAtt": [ - "NewswiresDBNewswires2A5A9AC6", - "Endpoint.Address", - ], - }, - "DATABASE_NAME": "newswires", - "DATABASE_PORT": { - "Fn::GetAtt": [ - "NewswiresDBNewswires2A5A9AC6", - "Endpoint.Port", - ], - }, - "FEEDS_BUCKET_NAME": { - "Ref": "feedsbucketTESTNewswires116BDB0E", - }, - "STACK": "editorial-feeds", - "STAGE": "TEST", - }, - }, - "Handler": "handler.main", - "LoggingConfig": { - "LogFormat": "JSON", - }, - "MemorySize": 512, - "ReservedConcurrentExecutions": 10, - "Role": { - "Fn::GetAtt": [ - "IngestionLambdaTESTServiceRole62DE083D", - "Arn", - ], - }, - "Runtime": "nodejs20.x", - "Tags": [ - { - "Key": "App", - "Value": "ingestion-lambda", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "Timeout": 30, - "VpcConfig": { - "SecurityGroupIds": [ - { - "Fn::GetAtt": [ - "IngestionLambdaTESTSecurityGroup5E6CBDBD", - "GroupId", - ], - }, - ], - "SubnetIds": { - "Ref": "newswiresPrivateSubnets", - }, - }, - }, - "Type": "AWS::Lambda::Function", - }, - "IngestionLambdaTESTSecurityGroup5E6CBDBD": { - "Properties": { - "GroupDescription": "Automatic security group for Lambda Function NewswiresIngestionLambdaTESTD558924B", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1", - }, - ], - "Tags": [ - { - "Key": "App", - "Value": "ingestion-lambda", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "VpcId": { - "Ref": "VpcId", - }, - }, - "Type": "AWS::EC2::SecurityGroup", - }, - "IngestionLambdaTESTServiceRole62DE083D": { - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com", - }, - }, - ], - "Version": "2012-10-17", - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", - ], - ], - }, + "OKActions": [ { "Fn::Join": [ "", [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole", - ], - ], - }, - ], - "Tags": [ - { - "Key": "App", - "Value": "ingestion-lambda", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - }, - "Type": "AWS::IAM::Role", - }, - "IngestionLambdaTESTServiceRoleDefaultPolicy92C2CE04": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*", - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":s3:::", - { - "Ref": "DistributionBucketName", - }, - ], - ], - }, + "arn:aws:sns:", { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":s3:::", - { - "Ref": "DistributionBucketName", - }, - "/editorial-feeds/TEST/ingestion-lambda/ingestion-lambda.zip", - ], - ], - }, - ], - }, - { - "Action": "ssm:GetParametersByPath", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:aws:ssm:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":parameter/TEST/editorial-feeds/ingestion-lambda", - ], - ], - }, - }, - { - "Action": [ - "ssm:GetParameters", - "ssm:GetParameter", - ], - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:aws:ssm:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":parameter/TEST/editorial-feeds/ingestion-lambda/*", - ], - ], - }, - }, - { - "Action": [ - "sqs:ReceiveMessage", - "sqs:ChangeMessageVisibility", - "sqs:GetQueueUrl", - "sqs:DeleteMessage", - "sqs:GetQueueAttributes", - ], - "Effect": "Allow", - "Resource": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", - }, - }, - { - "Action": [ - "sqs:ReceiveMessage", - "sqs:ChangeMessageVisibility", - "sqs:GetQueueUrl", - "sqs:DeleteMessage", - "sqs:GetQueueAttributes", - ], - "Effect": "Allow", - "Resource": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockFingerpostQueue05E3D7ECArnA85146B3", - }, - }, - { - "Action": [ - "s3:DeleteObject*", - "s3:PutObject", - "s3:PutObjectLegalHold", - "s3:PutObjectRetention", - "s3:PutObjectTagging", - "s3:PutObjectVersionTagging", - "s3:Abort*", - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "feedsbucketTESTNewswires116BDB0E", - "Arn", - ], - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "feedsbucketTESTNewswires116BDB0E", - "Arn", - ], - }, - "/*", - ], - ], - }, - ], - }, - { - "Action": "rds-db:connect", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":rds-db:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":dbuser:", - { - "Fn::GetAtt": [ - "NewswiresDBNewswires2A5A9AC6", - "DbiResourceId", - ], - }, - "/{{resolve:secretsmanager:", - { - "Ref": "NewswiresDBNewswiresSecretCF4DBD56", - }, - ":SecretString:username::}}", - ], - ], - }, - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "IngestionLambdaTESTServiceRoleDefaultPolicy92C2CE04", - "Roles": [ - { - "Ref": "IngestionLambdaTESTServiceRole62DE083D", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, - "IngestionLambdaTESTSqsEventSourcemockWiresFeedsMockFingerpostQueue19AE08DA454EF2E1": { - "Properties": { - "EventSourceArn": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockFingerpostQueue05E3D7ECArnA85146B3", - }, - "FunctionName": { - "Ref": "IngestionLambdaTESTC02B3E43", - }, - "FunctionResponseTypes": [ - "ReportBatchItemFailures", - ], - }, - "Type": "AWS::Lambda::EventSourceMapping", - }, - "IngestionLambdaTESTSqsEventSourcemockWiresFeedsMockSourceQueue17F9CFF698B624D6": { - "Properties": { - "EventSourceArn": { - "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", - }, - "FunctionName": { - "Ref": "IngestionLambdaTESTC02B3E43", - }, - "FunctionResponseTypes": [ - "ReportBatchItemFailures", - ], - }, - "Type": "AWS::Lambda::EventSourceMapping", - }, - "InstanceRoleNewswiresC10A0615": { - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "ec2.amazonaws.com", - }, - }, - ], - "Version": "2012-10-17", - }, - "Path": "/", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - }, - "Type": "AWS::IAM::Role", - }, - "InstanceRoleNewswiresDefaultPolicyA474C079": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "rds-db:connect", - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition", - }, - ":rds-db:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":dbuser:", - { - "Fn::GetAtt": [ - "NewswiresDBNewswires2A5A9AC6", - "DbiResourceId", - ], - }, - "/{{resolve:secretsmanager:", - { - "Ref": "NewswiresDBNewswiresSecretCF4DBD56", - }, - ":SecretString:username::}}", - ], - ], - }, - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "InstanceRoleNewswiresDefaultPolicyA474C079", - "Roles": [ - { - "Ref": "InstanceRoleNewswiresC10A0615", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, - "ListenerNewswires227C913D": { - "Properties": { - "Certificates": [ - { - "CertificateArn": { - "Ref": "CertificateNewswiresFEA3DE56", - }, - }, - ], - "DefaultActions": [ - { - "TargetGroupArn": { - "Ref": "TargetGroupNewswires87809E8A", - }, - "Type": "forward", - }, - ], - "LoadBalancerArn": { - "Ref": "LoadBalancerNewswires3B8BBCB3", - }, - "Port": 443, - "Protocol": "HTTPS", - "SslPolicy": "ELBSecurityPolicy-TLS13-1-2-2021-06", - }, - "Type": "AWS::ElasticLoadBalancingV2::Listener", - }, - "LoadBalancerNewswires3B8BBCB3": { - "Properties": { - "LoadBalancerAttributes": [ - { - "Key": "deletion_protection.enabled", - "Value": "true", - }, - { - "Key": "routing.http.x_amzn_tls_version_and_cipher_suite.enabled", - "Value": "true", - }, - { - "Key": "routing.http.drop_invalid_header_fields.enabled", - "Value": "true", - }, - ], - "Scheme": "internet-facing", - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "LoadBalancerNewswiresSecurityGroupF93D2107", - "GroupId", - ], - }, - ], - "Subnets": { - "Ref": "newswiresPublicSubnets", - }, - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "Type": "application", - }, - "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", - }, - "LoadBalancerNewswiresSecurityGroupF93D2107": { - "Properties": { - "GroupDescription": "Automatically created Security Group for ELB NewswiresLoadBalancerNewswires55D111EE", - "SecurityGroupIngress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow from anyone on port 443", - "FromPort": 443, - "IpProtocol": "tcp", - "ToPort": 443, - }, - ], - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "VpcId": { - "Ref": "VpcId", - }, - }, - "Type": "AWS::EC2::SecurityGroup", - }, - "LoadBalancerNewswiresSecurityGrouptoNewswiresDefaultSecurityGroupNewswires40BF4E639000CA7B98AE": { - "Properties": { - "Description": "Load balancer to target", - "DestinationSecurityGroupId": { - "Fn::GetAtt": [ - "DefaultSecurityGroupNewswires91CCC0BF", - "GroupId", - ], - }, - "FromPort": 9000, - "GroupId": { - "Fn::GetAtt": [ - "LoadBalancerNewswiresSecurityGroupF93D2107", - "GroupId", - ], - }, - "IpProtocol": "tcp", - "ToPort": 9000, - }, - "Type": "AWS::EC2::SecurityGroupEgress", - }, - "LoadBalancerNewswiresSecurityGrouptoNewswiresGuHttpsEgressSecurityGroupNewswires371358559000483685BB": { - "Properties": { - "Description": "Load balancer to target", - "DestinationSecurityGroupId": { - "Fn::GetAtt": [ - "GuHttpsEgressSecurityGroupNewswiresEF9436B0", - "GroupId", - ], - }, - "FromPort": 9000, - "GroupId": { - "Fn::GetAtt": [ - "LoadBalancerNewswiresSecurityGroupF93D2107", - "GroupId", - ], - }, - "IpProtocol": "tcp", - "ToPort": 9000, - }, - "Type": "AWS::EC2::SecurityGroupEgress", - }, - "LoadBalancerNewswiresSecurityGrouptoNewswiresWazuhSecurityGroupCCE261159000C5B90044": { - "Properties": { - "Description": "Load balancer to target", - "DestinationSecurityGroupId": { - "Fn::GetAtt": [ - "WazuhSecurityGroup", - "GroupId", - ], - }, - "FromPort": 9000, - "GroupId": { - "Fn::GetAtt": [ - "LoadBalancerNewswiresSecurityGroupF93D2107", - "GroupId", - ], - }, - "IpProtocol": "tcp", - "ToPort": 9000, - }, - "Type": "AWS::EC2::SecurityGroupEgress", - }, - "NewswiresDBNewswires2A5A9AC6": { - "DeletionPolicy": "Snapshot", - "Properties": { - "AllocatedStorage": "100", - "AutoMinorVersionUpgrade": false, - "CACertificateIdentifier": "rds-ca-rsa2048-g1", - "CopyTagsToSnapshot": true, - "DBInstanceClass": "db.t4g.small", - "DBName": "newswires", - "DBSubnetGroupName": { - "Ref": "NewswiresDBNewswiresSubnetGroupC2336A30", - }, - "DeletionProtection": true, - "EnableIAMDatabaseAuthentication": true, - "Engine": "postgres", - "EngineVersion": "16.4", - "Iops": 3000, - "MasterUserPassword": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "NewswiresDBNewswiresSecretCF4DBD56", - }, - ":SecretString:password::}}", - ], - ], - }, - "MasterUsername": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "NewswiresDBNewswiresSecretCF4DBD56", - }, - ":SecretString:username::}}", - ], - ], - }, - "MultiAZ": false, - "Port": "5432", - "PubliclyAccessible": false, - "StorageEncrypted": true, - "StorageThroughput": 125, - "StorageType": "gp3", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "devx-backup-enabled", - "Value": "true", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "VPCSecurityGroups": [ - { - "Fn::GetAtt": [ - "DefaultSecurityGroupNewswires91CCC0BF", - "GroupId", - ], - }, - ], - }, - "Type": "AWS::RDS::DBInstance", - "UpdateReplacePolicy": "Snapshot", - }, - "NewswiresDBNewswiresAccessSecurityGroupParamEEED45CA": { - "Properties": { - "DataType": "text", - "Name": "/TEST/editorial-feeds/newswires/database/access-security-group", - "Tags": { - "App": "newswires", - "Stack": "editorial-feeds", - "Stage": "TEST", - "gu:cdk:version": "TEST", - "gu:repo": "guardian/newswires", - }, - "Tier": "Standard", - "Type": "String", - "Value": { - "Fn::GetAtt": [ - "DefaultSecurityGroupNewswires91CCC0BF", - "GroupId", - ], - }, - }, - "Type": "AWS::SSM::Parameter", - }, - "NewswiresDBNewswiresDatabaseNameParam46DC31AD": { - "Properties": { - "DataType": "text", - "Name": "/TEST/editorial-feeds/newswires/database/database-name", - "Tags": { - "App": "newswires", - "Stack": "editorial-feeds", - "Stage": "TEST", - "gu:cdk:version": "TEST", - "gu:repo": "guardian/newswires", - }, - "Tier": "Standard", - "Type": "String", - "Value": "newswires", - }, - "Type": "AWS::SSM::Parameter", - }, - "NewswiresDBNewswiresEndpointAddressParam62BDC1A2": { - "Properties": { - "DataType": "text", - "Name": "/TEST/editorial-feeds/newswires/database/endpoint-address", - "Tags": { - "App": "newswires", - "Stack": "editorial-feeds", - "Stage": "TEST", - "gu:cdk:version": "TEST", - "gu:repo": "guardian/newswires", - }, - "Tier": "Standard", - "Type": "String", - "Value": { - "Fn::GetAtt": [ - "NewswiresDBNewswires2A5A9AC6", - "Endpoint.Address", - ], - }, - }, - "Type": "AWS::SSM::Parameter", - }, - "NewswiresDBNewswiresPortParam6F050C46": { - "Properties": { - "DataType": "text", - "Name": "/TEST/editorial-feeds/newswires/database/port", - "Tags": { - "App": "newswires", - "Stack": "editorial-feeds", - "Stage": "TEST", - "gu:cdk:version": "TEST", - "gu:repo": "guardian/newswires", - }, - "Tier": "Standard", - "Type": "String", - "Value": { - "Fn::GetAtt": [ - "NewswiresDBNewswires2A5A9AC6", - "Endpoint.Port", - ], - }, - }, - "Type": "AWS::SSM::Parameter", - }, - "NewswiresDBNewswiresSecretAttachment35EF265F": { - "Properties": { - "SecretId": { - "Ref": "NewswiresDBNewswiresSecretCF4DBD56", - }, - "TargetId": { - "Ref": "NewswiresDBNewswires2A5A9AC6", - }, - "TargetType": "AWS::RDS::DBInstance", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "NewswiresDBNewswiresSecretCF4DBD56": { - "DeletionPolicy": "Delete", - "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], ], - ], - }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"postgres"}", - }, + }, + ], "Tags": [ { "Key": "App", @@ -3181,16 +2475,76 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], + "Threshold": 0, + "TreatMissingData": "notBreaching", }, - "Type": "AWS::SecretsManager::Secret", - "UpdateReplacePolicy": "Delete", + "Type": "AWS::CloudWatch::Alarm", }, - "NewswiresDBNewswiresSubnetGroupC2336A30": { + "reutersLambdaHaywireAlarm583979E8": { "Properties": { - "DBSubnetGroupDescription": "Subnet group for NewswiresDBNewswires database", - "SubnetIds": { - "Ref": "newswiresPrivateSubnets", - }, + "ActionsEnabled": true, + "AlarmActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "AlarmDescription": "The editorial-feeds-TEST-reuters_poller_lambda has potentially gone haywire (has been invoked more frequently than expected).", + "AlarmName": "editorial-feeds-TEST-reuters_poller_lambda_Haywire_Alarm", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "FunctionName", + "Value": "editorial-feeds-TEST-reuters_poller_lambda", + }, + ], + "EvaluationPeriods": 1, + "MetricName": "Invocations", + "Namespace": "AWS/Lambda", + "OKActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "Period": 300, + "Statistic": "Sum", "Tags": [ { "Key": "App", @@ -3213,62 +2567,141 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], + "Threshold": 7.5, + "TreatMissingData": "notBreaching", }, - "Type": "AWS::RDS::DBSubnetGroup", + "Type": "AWS::CloudWatch::Alarm", }, - "NewswiresDBNewswiresUsernameParam880243B7": { + "reutersLambdaQueue7636161A": { + "DeletionPolicy": "Delete", "Properties": { - "DataType": "text", - "Name": "/TEST/editorial-feeds/newswires/database/username", - "Tags": { - "App": "newswires", - "Stack": "editorial-feeds", - "Stage": "TEST", - "gu:cdk:version": "TEST", - "gu:repo": "guardian/newswires", - }, - "Tier": "Standard", - "Type": "String", - "Value": "postgres", + "MessageRetentionPeriod": 300, + "QueueName": "editorial-feeds-TEST-reuters_poller_lambda_queue", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "VisibilityTimeout": 60, }, - "Type": "AWS::SSM::Parameter", + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", }, - "PandaAuthPolicy4E029301": { + "reutersLambdaServiceRoleB1396562": { "Properties": { - "PolicyDocument": { + "AssumeRolePolicyDocument": { "Statement": [ { - "Action": "s3:GetObject", + "Action": "sts:AssumeRole", "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:aws:s3:::", - { - "Ref": "PanDomainSettingsBucket", - }, - "/*", - ], - ], + "Principal": { + "Service": "lambda.amazonaws.com", }, }, ], "Version": "2012-10-17", }, - "PolicyName": "PandaAuthPolicy4E029301", - "Roles": [ + "ManagedPolicyArns": [ { - "Ref": "InstanceRoleNewswiresC10A0615", + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + ], + ], + }, + ], + "Tags": [ + { + "Key": "App", + "Value": "reuters_poller_lambda", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", }, ], }, - "Type": "AWS::IAM::Policy", + "Type": "AWS::IAM::Role", }, - "ParameterStoreReadNewswiresF3917A8D": { + "reutersLambdaServiceRoleDefaultPolicy86486920": { "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Ref": "DistributionBucketName", + }, + ], + ], + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Ref": "DistributionBucketName", + }, + "/editorial-feeds/TEST/reuters_poller_lambda/poller-lambdas.zip", + ], + ], + }, + ], + }, { "Action": "ssm:GetParametersByPath", "Effect": "Allow", @@ -3284,7 +2717,7 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/editorial-feeds/newswires", + ":parameter/TEST/editorial-feeds/reuters_poller_lambda", ], ], }, @@ -3307,141 +2740,90 @@ exports[`The Newswires stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/editorial-feeds/newswires/*", + ":parameter/TEST/editorial-feeds/reuters_poller_lambda/*", ], ], }, }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "parameter-store-read-policy", - "Roles": [ - { - "Ref": "InstanceRoleNewswiresC10A0615", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, - "PermissionsCachePolicyEB49F1A4": { - "Properties": { - "PolicyDocument": { - "Statement": [ { - "Action": "s3:GetObject", + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + ], + "Effect": "Allow", + "Resource": { + "Ref": "reutersSecretA9E37489", + }, + }, + { + "Action": [ + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", + "sqs:GetQueueUrl", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes", + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "reutersLambdaQueue7636161A", + "Arn", + ], + }, + }, + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], "Effect": "Allow", "Resource": { - "Fn::Join": [ - "", - [ - "arn:aws:s3:::", - { - "Ref": "PermissionsBucket", - }, - "/TEST/*", - ], + "Fn::GetAtt": [ + "reutersLambdaQueue7636161A", + "Arn", ], }, }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "PermissionsCachePolicyEB49F1A4", - "Roles": [ - { - "Ref": "InstanceRoleNewswiresC10A0615", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, - "SsmSshPolicy4CFC977E": { - "Properties": { - "PolicyDocument": { - "Statement": [ { "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", ], "Effect": "Allow", - "Resource": "*", + "Resource": { + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", + }, }, ], "Version": "2012-10-17", }, - "PolicyName": "ssm-ssh-policy", + "PolicyName": "reutersLambdaServiceRoleDefaultPolicy86486920", "Roles": [ { - "Ref": "InstanceRoleNewswiresC10A0615", + "Ref": "reutersLambdaServiceRoleB1396562", }, ], }, "Type": "AWS::IAM::Policy", }, - "TargetGroupNewswires87809E8A": { + "reutersLambdaSqsEventSourceNewswiresreutersLambdaQueue461D5765E7006B8A": { "Properties": { - "HealthCheckIntervalSeconds": 10, - "HealthCheckPath": "/healthcheck", - "HealthCheckProtocol": "HTTP", - "HealthCheckTimeoutSeconds": 5, - "HealthyThresholdCount": 5, - "Port": 9000, - "Protocol": "HTTP", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, - ], - "TargetGroupAttributes": [ - { - "Key": "deregistration_delay.timeout_seconds", - "Value": "30", - }, - { - "Key": "stickiness.enabled", - "Value": "false", - }, - ], - "TargetType": "instance", - "UnhealthyThresholdCount": 2, - "VpcId": { - "Ref": "VpcId", + "BatchSize": 1, + "EventSourceArn": { + "Fn::GetAtt": [ + "reutersLambdaQueue7636161A", + "Arn", + ], + }, + "FunctionName": { + "Ref": "reutersLambda21FE513B", }, }, - "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Type": "AWS::Lambda::EventSourceMapping", }, - "UnhealthyInstancesAlarmNewswires7AAD87B6": { + "reutersLambdaStalledAlarm9A0557EB": { "Properties": { "ActionsEnabled": true, "AlarmActions": [ @@ -3468,127 +2850,44 @@ exports[`The Newswires stack matches the snapshot 1`] = ` ], }, ], - "AlarmDescription": "newswires's instances have failed healthchecks several times over the last 1 hour. - This typically results in the AutoScaling Group cycling instances and can lead to problems with deployment, - scaling or handling traffic spikes. - - Check newswires's application logs or ssh onto an unhealthy instance in order to debug these problems.", - "AlarmName": "Unhealthy instances for newswires in TEST", - "ComparisonOperator": "GreaterThanOrEqualToThreshold", - "DatapointsToAlarm": 30, + "AlarmDescription": "The editorial-feeds-TEST-reuters_poller_lambda is potentially stalled (hasn't been invoked as frequently as expected).", + "AlarmName": "editorial-feeds-TEST-reuters_poller_lambda_Stalled_Alarm", + "ComparisonOperator": "LessThanThreshold", "Dimensions": [ { - "Name": "LoadBalancer", - "Value": { - "Fn::Join": [ - "", - [ - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - "/", - { - "Ref": "ListenerNewswires227C913D", - }, - ], - }, - ], - }, - "/", - { - "Fn::Select": [ - 2, - { - "Fn::Split": [ - "/", - { - "Ref": "ListenerNewswires227C913D", - }, - ], - }, - ], - }, - "/", - { - "Fn::Select": [ - 3, - { - "Fn::Split": [ - "/", - { - "Ref": "ListenerNewswires227C913D", - }, - ], - }, - ], - }, - ], - ], - }, - }, - { - "Name": "TargetGroup", - "Value": { - "Fn::GetAtt": [ - "TargetGroupNewswires87809E8A", - "TargetGroupFullName", - ], - }, - }, - ], - "EvaluationPeriods": 60, - "MetricName": "UnHealthyHostCount", - "Namespace": "AWS/ApplicationELB", - "Period": 60, - "Statistic": "Maximum", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", + "Name": "FunctionName", + "Value": "editorial-feeds-TEST-reuters_poller_lambda", }, ], - "Threshold": 1, - "TreatMissingData": "notBreaching", - }, - "Type": "AWS::CloudWatch::Alarm", - }, - "WazuhSecurityGroup": { - "Properties": { - "GroupDescription": "Allow outbound traffic from wazuh agent to manager", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Wazuh event logging", - "FromPort": 1514, - "IpProtocol": "tcp", - "ToPort": 1514, - }, + "EvaluationPeriods": 1, + "MetricName": "Invocations", + "Namespace": "AWS/Lambda", + "OKActions": [ { - "CidrIp": "0.0.0.0/0", - "Description": "Wazuh agent registration", - "FromPort": 1515, - "IpProtocol": "tcp", - "ToPort": 1515, + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], }, ], + "Period": 900, + "Statistic": "Sum", "Tags": [ { "Key": "App", @@ -3611,207 +2910,78 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "Value": "TEST", }, ], - "VpcId": { - "Ref": "VpcId", - }, - }, - "Type": "AWS::EC2::SecurityGroup", - }, - "WazuhSecurityGroupfromNewswiresLoadBalancerNewswiresSecurityGroup255ABDD190009D3830D6": { - "Properties": { - "Description": "Load balancer to target", - "FromPort": 9000, - "GroupId": { - "Fn::GetAtt": [ - "WazuhSecurityGroup", - "GroupId", - ], - }, - "IpProtocol": "tcp", - "SourceSecurityGroupId": { - "Fn::GetAtt": [ - "LoadBalancerNewswiresSecurityGroupF93D2107", - "GroupId", - ], - }, - "ToPort": 9000, + "Threshold": 15, + "TreatMissingData": "breaching", }, - "Type": "AWS::EC2::SecurityGroupIngress", + "Type": "AWS::CloudWatch::Alarm", }, - "editorialfeedsTESTnewswires01BC2EBA": { - "DependsOn": [ - "InstanceRoleNewswiresDefaultPolicyA474C079", - "InstanceRoleNewswiresC10A0615", - ], + "reutersLambdaThrottlingAlarmForLambdaE74C58AB": { "Properties": { - "LaunchTemplateData": { - "IamInstanceProfile": { - "Arn": { - "Fn::GetAtt": [ - "editorialfeedsTESTnewswiresProfileD57DD674", - "Arn", - ], - }, - }, - "ImageId": { - "Ref": "AMINewswires", - }, - "InstanceType": "t4g.small", - "MetadataOptions": { - "HttpTokens": "required", - "InstanceMetadataTags": "enabled", - }, - "SecurityGroupIds": [ - { - "Fn::GetAtt": [ - "GuHttpsEgressSecurityGroupNewswiresEF9436B0", - "GroupId", - ], - }, - { - "Fn::GetAtt": [ - "WazuhSecurityGroup", - "GroupId", - ], - }, - { - "Fn::GetAtt": [ - "DefaultSecurityGroupNewswires91CCC0BF", - "GroupId", - ], - }, - ], - "TagSpecifications": [ - { - "ResourceType": "instance", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, + "ActionsEnabled": true, + "AlarmActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", { - "Key": "Name", - "Value": "Newswires/editorial-feeds-TEST-newswires", + "Ref": "AWS::Region", }, + ":", { - "Key": "Stack", - "Value": "editorial-feeds", + "Ref": "AWS::AccountId", }, + ":", { - "Key": "Stage", - "Value": "TEST", + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], }, ], + ], + }, + ], + "AlarmDescription": "The editorial-feeds-TEST-reuters_poller_lambda is throttling.", + "AlarmName": "editorial-feeds-TEST-reuters_poller_lambda_Throttling_Alarm", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "FunctionName", + "Value": { + "Ref": "reutersLambda21FE513B", }, - { - "ResourceType": "volume", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "Throttles", + "Namespace": "AWS/Lambda", + "OKActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", { - "Key": "Name", - "Value": "Newswires/editorial-feeds-TEST-newswires", + "Ref": "AWS::Region", }, + ":", { - "Key": "Stack", - "Value": "editorial-feeds", + "Ref": "AWS::AccountId", }, + ":", { - "Key": "Stage", - "Value": "TEST", + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], }, ], - }, - ], - "UserData": { - "Fn::Base64": { - "Fn::Join": [ - "", - [ - "#!/bin/bash -mkdir -p $(dirname '/newswires/newswires.deb') -aws s3 cp 's3://", - { - "Ref": "DistributionBucketName", - }, - "/editorial-feeds/TEST/newswires/newswires.deb' '/newswires/newswires.deb' -dpkg -i /newswires/newswires.deb", - ], - ], - }, - }, - }, - "TagSpecifications": [ - { - "ResourceType": "launch-template", - "Tags": [ - { - "Key": "App", - "Value": "newswires", - }, - { - "Key": "gu:cdk:version", - "Value": "TEST", - }, - { - "Key": "gu:repo", - "Value": "guardian/newswires", - }, - { - "Key": "Name", - "Value": "Newswires/editorial-feeds-TEST-newswires", - }, - { - "Key": "Stack", - "Value": "editorial-feeds", - }, - { - "Key": "Stage", - "Value": "TEST", - }, ], }, ], - }, - "Type": "AWS::EC2::LaunchTemplate", - }, - "editorialfeedsTESTnewswiresProfileD57DD674": { - "Properties": { - "Roles": [ - { - "Ref": "InstanceRoleNewswiresC10A0615", - }, - ], - }, - "Type": "AWS::IAM::InstanceProfile", - }, - "feedsbucketTESTNewswires116BDB0E": { - "DeletionPolicy": "Retain", - "Properties": { - "PublicAccessBlockConfiguration": { - "BlockPublicAcls": true, - "BlockPublicPolicy": true, - "IgnorePublicAcls": true, - "RestrictPublicBuckets": true, - }, + "Period": 60, + "Statistic": "Sum", "Tags": [ { "Key": "App", @@ -3834,15 +3004,17 @@ dpkg -i /newswires/newswires.deb", "Value": "TEST", }, ], - "VersioningConfiguration": { - "Status": "Enabled", - }, + "Threshold": 0, + "TreatMissingData": "notBreaching", }, - "Type": "AWS::S3::Bucket", - "UpdateReplacePolicy": "Retain", + "Type": "AWS::CloudWatch::Alarm", }, - "newswiresemailalarmtopicB2906D97": { + "reutersSecretA9E37489": { + "DeletionPolicy": "Delete", "Properties": { + "Description": "Secret for the reuters poller lambda", + "GenerateSecretString": {}, + "Name": "/TEST/editorial-feeds/newswires/reuters_poller_lambda", "Tags": [ { "Key": "App", @@ -3866,7 +3038,8 @@ dpkg -i /newswires/newswires.deb", }, ], }, - "Type": "AWS::SNS::Topic", + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", }, }, } diff --git a/cdk/lib/__snapshots__/riffraff.test.ts.snap b/cdk/lib/__snapshots__/riffraff.test.ts.snap index 89a9d18..6674b39 100644 --- a/cdk/lib/__snapshots__/riffraff.test.ts.snap +++ b/cdk/lib/__snapshots__/riffraff.test.ts.snap @@ -31,27 +31,13 @@ deployments: fileName: ingestion-lambda.zip actions: - uploadLambda - lambda-upload-eu-west-1-editorial-feeds-EXAMPLE_long_polling_poller_lambda: + lambda-upload-eu-west-1-editorial-feeds-reuters_poller_lambda: type: aws-lambda stacks: - editorial-feeds regions: - eu-west-1 - app: EXAMPLE_long_polling_poller_lambda - contentDirectory: poller-lambdas - parameters: - bucketSsmLookup: true - lookupByTags: true - fileName: poller-lambdas.zip - actions: - - uploadLambda - lambda-upload-eu-west-1-editorial-feeds-EXAMPLE_fixed_frequency_poller_lambda: - type: aws-lambda - stacks: - - editorial-feeds - regions: - - eu-west-1 - app: EXAMPLE_fixed_frequency_poller_lambda + app: reuters_poller_lambda contentDirectory: poller-lambdas parameters: bucketSsmLookup: true @@ -92,10 +78,7 @@ deployments: Encrypted: 'true' dependencies: - lambda-upload-eu-west-1-editorial-feeds-ingestion-lambda - - >- - lambda-upload-eu-west-1-editorial-feeds-EXAMPLE_long_polling_poller_lambda - - >- - lambda-upload-eu-west-1-editorial-feeds-EXAMPLE_fixed_frequency_poller_lambda + - lambda-upload-eu-west-1-editorial-feeds-reuters_poller_lambda - asg-upload-eu-west-1-editorial-feeds-newswires - cfn-eu-west-1-editorial-feeds-wires-feeds lambda-update-eu-west-1-editorial-feeds-ingestion-lambda: @@ -114,29 +97,13 @@ deployments: - updateLambda dependencies: - cfn-eu-west-1-editorial-feeds-newswires - lambda-update-eu-west-1-editorial-feeds-EXAMPLE_long_polling_poller_lambda: - type: aws-lambda - stacks: - - editorial-feeds - regions: - - eu-west-1 - app: EXAMPLE_long_polling_poller_lambda - contentDirectory: poller-lambdas - parameters: - bucketSsmLookup: true - lookupByTags: true - fileName: poller-lambdas.zip - actions: - - updateLambda - dependencies: - - cfn-eu-west-1-editorial-feeds-newswires - lambda-update-eu-west-1-editorial-feeds-EXAMPLE_fixed_frequency_poller_lambda: + lambda-update-eu-west-1-editorial-feeds-reuters_poller_lambda: type: aws-lambda stacks: - editorial-feeds regions: - eu-west-1 - app: EXAMPLE_fixed_frequency_poller_lambda + app: reuters_poller_lambda contentDirectory: poller-lambdas parameters: bucketSsmLookup: true diff --git a/package.json b/package.json index 7d9b2a6..8562acd 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,21 @@ "cdk.out", ".eslintrc.js", "jest.config.js" - ] + ], + "rules": { + "@typescript-eslint/no-unused-vars": [ + "error", + { + "args": "all", + "argsIgnorePattern": "^_", + "caughtErrors": "all", + "caughtErrorsIgnorePattern": "^_", + "destructuredArrayIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "ignoreRestSiblings": true + } + ] + } }, "dependencies": { "zod": "3.23.8" diff --git a/poller-lambdas/src/index.ts b/poller-lambdas/src/index.ts index cc33068..041b8d7 100644 --- a/poller-lambdas/src/index.ts +++ b/poller-lambdas/src/index.ts @@ -5,8 +5,7 @@ import type { PollerId } from '../../shared/pollers'; import { POLLER_LAMBDA_ENV_VAR_KEYS } from '../../shared/pollers'; import { queueNextInvocation, secretsManager, sqs } from './aws'; import { getEnvironmentVariableOrCrash } from './config'; -import { EXAMPLE_fixed_frequency } from './pollers/EXAMPLE_fixed_frequency'; -import { EXAMPLE_long_polling } from './pollers/EXAMPLE_long_polling'; +import { reutersPoller } from './pollers/reuters/reutersPoller'; import type { HandlerInputSqsPayload, PollFunction } from './types'; import { isFixedFrequencyPollOutput } from './types'; @@ -100,8 +99,9 @@ const pollerWrapper = }; export const handlers = { - EXAMPLE_long_polling: pollerWrapper(EXAMPLE_long_polling), - EXAMPLE_fixed_frequency: pollerWrapper(EXAMPLE_fixed_frequency), + // EXAMPLE_long_polling: pollerWrapper(EXAMPLE_long_polling), + // EXAMPLE_fixed_frequency: pollerWrapper(EXAMPLE_fixed_frequency), + reuters: pollerWrapper(reutersPoller), } satisfies Record< PollerId, (sqsEvent: HandlerInputSqsPayload) => Promise diff --git a/poller-lambdas/src/pollers/reuters/reutersPoller.ts b/poller-lambdas/src/pollers/reuters/reutersPoller.ts new file mode 100644 index 0000000..deaa6a4 --- /dev/null +++ b/poller-lambdas/src/pollers/reuters/reutersPoller.ts @@ -0,0 +1,18 @@ +import type { + FixedFrequencyPollFunction, + PollerInput, + SecretValue, +} from '../../types'; + +export const reutersPoller = (async ( + _secret: SecretValue, + _input: PollerInput, +) => { + console.log('Reuters poller running'); + await new Promise((resolve) => setTimeout(resolve, 1000)); + return { + payloadForIngestionLambda: [], + valueForNextPoll: '', + idealFrequencyInSeconds: 30, + }; +}) satisfies FixedFrequencyPollFunction; diff --git a/shared/pollers.ts b/shared/pollers.ts index 4aa3ae2..bcf1ed5 100644 --- a/shared/pollers.ts +++ b/shared/pollers.ts @@ -24,6 +24,7 @@ export type PollerConfig = PollerLambdaProps & { export type PollerId = keyof typeof POLLERS_CONFIG; export const POLLERS_CONFIG = { - EXAMPLE_long_polling: {}, - EXAMPLE_fixed_frequency: { idealFrequencyInSeconds: 30 }, + // EXAMPLE_long_polling: {}, + // EXAMPLE_fixed_frequency: { idealFrequencyInSeconds: 30 }, + reuters: { idealFrequencyInSeconds: 60 }, } as const satisfies Record; // used to generate lambda etc. per agency, with config mapped From 9c2816cf2899e729b64518ce26a7858f80af7696 Mon Sep 17 00:00:00 2001 From: Pete F Date: Mon, 13 Jan 2025 11:56:57 +0000 Subject: [PATCH 3/4] Minimal AP poller setup --- cdk/lib/__snapshots__/newswires.test.ts.snap | 827 +++++++++++++++++++ cdk/lib/__snapshots__/riffraff.test.ts.snap | 31 + poller-lambdas/src/index.ts | 2 + poller-lambdas/src/pollers/ap/apPoller.ts | 10 + shared/pollers.ts | 1 + 5 files changed, 871 insertions(+) create mode 100644 poller-lambdas/src/pollers/ap/apPoller.ts diff --git a/cdk/lib/__snapshots__/newswires.test.ts.snap b/cdk/lib/__snapshots__/newswires.test.ts.snap index ab7585e..a033061 100644 --- a/cdk/lib/__snapshots__/newswires.test.ts.snap +++ b/cdk/lib/__snapshots__/newswires.test.ts.snap @@ -18,6 +18,11 @@ exports[`The Newswires stack matches the snapshot 1`] = ` "GuLambdaThrottlingAlarm", "GuAlarm", "GuAlarm", + "GuLambdaFunction", + "GuLambdaErrorPercentageAlarm", + "GuLambdaThrottlingAlarm", + "GuAlarm", + "GuAlarm", "GuGetS3ObjectsPolicy", "GuGetS3ObjectsPolicy", "GuSubnetListParameter", @@ -1989,6 +1994,828 @@ exports[`The Newswires stack matches the snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroupIngress", }, + "apPollerLambdaCA07C49A": { + "DependsOn": [ + "apPollerLambdaServiceRoleDefaultPolicy1EF8D631", + "apPollerLambdaServiceRole1992B661", + ], + "Properties": { + "Architectures": [ + "arm64", + ], + "Code": { + "S3Bucket": { + "Ref": "DistributionBucketName", + }, + "S3Key": "editorial-feeds/TEST/apPoller_poller_lambda/poller-lambdas.zip", + }, + "Environment": { + "Variables": { + "APP": "apPoller_poller_lambda", + "INGESTION_LAMBDA_QUEUE_URL": { + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputRefMockSourceQueue20B4D8C006FBA8DA", + }, + "OWN_QUEUE_URL": { + "Ref": "apPollerLambdaQueueCEBF3221", + }, + "SECRET_NAME": { + "Fn::Join": [ + "-", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "-", + { + "Fn::Select": [ + 6, + { + "Fn::Split": [ + ":", + { + "Ref": "apPollerSecret4DA8E7BD", + }, + ], + }, + ], + }, + ], + }, + ], + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "-", + { + "Fn::Select": [ + 6, + { + "Fn::Split": [ + ":", + { + "Ref": "apPollerSecret4DA8E7BD", + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + ], + }, + "STACK": "editorial-feeds", + "STAGE": "TEST", + }, + }, + "FunctionName": "editorial-feeds-TEST-apPoller_poller_lambda", + "Handler": "index.handlers.apPoller", + "LoggingConfig": { + "LogFormat": "JSON", + }, + "MemorySize": 128, + "RecursiveLoop": "Allow", + "ReservedConcurrentExecutions": 2, + "Role": { + "Fn::GetAtt": [ + "apPollerLambdaServiceRole1992B661", + "Arn", + ], + }, + "Runtime": "nodejs20.x", + "Tags": [ + { + "Key": "App", + "Value": "apPoller_poller_lambda", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "Timeout": 60, + }, + "Type": "AWS::Lambda::Function", + }, + "apPollerLambdaErrorPercentageAlarmForLambda18550835": { + "Properties": { + "ActionsEnabled": true, + "AlarmActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "AlarmDescription": "The editorial-feeds-TEST-apPoller_poller_lambda is erroring.", + "AlarmName": "editorial-feeds-TEST-apPoller_poller_lambda_Error_Alarm", + "ComparisonOperator": "GreaterThanThreshold", + "EvaluationPeriods": 1, + "Metrics": [ + { + "Expression": "100*m1/m2", + "Id": "expr_1", + "Label": { + "Fn::Join": [ + "", + [ + "Error % of ", + { + "Ref": "apPollerLambdaCA07C49A", + }, + ], + ], + }, + }, + { + "Id": "m1", + "MetricStat": { + "Metric": { + "Dimensions": [ + { + "Name": "FunctionName", + "Value": { + "Ref": "apPollerLambdaCA07C49A", + }, + }, + ], + "MetricName": "Errors", + "Namespace": "AWS/Lambda", + }, + "Period": 60, + "Stat": "Sum", + }, + "ReturnData": false, + }, + { + "Id": "m2", + "MetricStat": { + "Metric": { + "Dimensions": [ + { + "Name": "FunctionName", + "Value": { + "Ref": "apPollerLambdaCA07C49A", + }, + }, + ], + "MetricName": "Invocations", + "Namespace": "AWS/Lambda", + }, + "Period": 60, + "Stat": "Sum", + }, + "ReturnData": false, + }, + ], + "OKActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "Threshold": 0, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "apPollerLambdaHaywireAlarm8A959E3F": { + "Properties": { + "ActionsEnabled": true, + "AlarmActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "AlarmDescription": "The editorial-feeds-TEST-apPoller_poller_lambda has potentially gone haywire (has been invoked more frequently than expected).", + "AlarmName": "editorial-feeds-TEST-apPoller_poller_lambda_Haywire_Alarm", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "FunctionName", + "Value": "editorial-feeds-TEST-apPoller_poller_lambda", + }, + ], + "EvaluationPeriods": 1, + "MetricName": "Invocations", + "Namespace": "AWS/Lambda", + "OKActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "Period": 60, + "Statistic": "Sum", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "Threshold": 60, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "apPollerLambdaQueueCEBF3221": { + "DeletionPolicy": "Delete", + "Properties": { + "MessageRetentionPeriod": 300, + "QueueName": "editorial-feeds-TEST-apPoller_poller_lambda_queue", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "VisibilityTimeout": 60, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "apPollerLambdaServiceRole1992B661": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + ], + ], + }, + ], + "Tags": [ + { + "Key": "App", + "Value": "apPoller_poller_lambda", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + "Type": "AWS::IAM::Role", + }, + "apPollerLambdaServiceRoleDefaultPolicy1EF8D631": { + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Ref": "DistributionBucketName", + }, + ], + ], + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Ref": "DistributionBucketName", + }, + "/editorial-feeds/TEST/apPoller_poller_lambda/poller-lambdas.zip", + ], + ], + }, + ], + }, + { + "Action": "ssm:GetParametersByPath", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":parameter/TEST/editorial-feeds/apPoller_poller_lambda", + ], + ], + }, + }, + { + "Action": [ + "ssm:GetParameters", + "ssm:GetParameter", + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":parameter/TEST/editorial-feeds/apPoller_poller_lambda/*", + ], + ], + }, + }, + { + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + ], + "Effect": "Allow", + "Resource": { + "Ref": "apPollerSecret4DA8E7BD", + }, + }, + { + "Action": [ + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", + "sqs:GetQueueUrl", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes", + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "apPollerLambdaQueueCEBF3221", + "Arn", + ], + }, + }, + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "apPollerLambdaQueueCEBF3221", + "Arn", + ], + }, + }, + { + "Action": [ + "sqs:SendMessage", + "sqs:GetQueueAttributes", + "sqs:GetQueueUrl", + ], + "Effect": "Allow", + "Resource": { + "Fn::ImportValue": "mockWiresFeeds:ExportsOutputFnGetAttMockSourceQueue20B4D8C0ArnCE5A6D0C", + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "apPollerLambdaServiceRoleDefaultPolicy1EF8D631", + "Roles": [ + { + "Ref": "apPollerLambdaServiceRole1992B661", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + "apPollerLambdaSqsEventSourceNewswiresapPollerLambdaQueue911BC96A52716070": { + "Properties": { + "BatchSize": 1, + "EventSourceArn": { + "Fn::GetAtt": [ + "apPollerLambdaQueueCEBF3221", + "Arn", + ], + }, + "FunctionName": { + "Ref": "apPollerLambdaCA07C49A", + }, + }, + "Type": "AWS::Lambda::EventSourceMapping", + }, + "apPollerLambdaStalledAlarm5E199779": { + "Properties": { + "ActionsEnabled": true, + "AlarmActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "AlarmDescription": "The editorial-feeds-TEST-apPoller_poller_lambda is potentially stalled (hasn't been invoked as frequently as expected).", + "AlarmName": "editorial-feeds-TEST-apPoller_poller_lambda_Stalled_Alarm", + "ComparisonOperator": "LessThanThreshold", + "Dimensions": [ + { + "Name": "FunctionName", + "Value": "editorial-feeds-TEST-apPoller_poller_lambda", + }, + ], + "EvaluationPeriods": 1, + "MetricName": "Invocations", + "Namespace": "AWS/Lambda", + "OKActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "Period": 180, + "Statistic": "Sum", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "Threshold": 1, + "TreatMissingData": "breaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "apPollerLambdaThrottlingAlarmForLambda9B677431": { + "Properties": { + "ActionsEnabled": true, + "AlarmActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "AlarmDescription": "The editorial-feeds-TEST-apPoller_poller_lambda is throttling.", + "AlarmName": "editorial-feeds-TEST-apPoller_poller_lambda_Throttling_Alarm", + "ComparisonOperator": "GreaterThanThreshold", + "Dimensions": [ + { + "Name": "FunctionName", + "Value": { + "Ref": "apPollerLambdaCA07C49A", + }, + }, + ], + "EvaluationPeriods": 1, + "MetricName": "Throttles", + "Namespace": "AWS/Lambda", + "OKActions": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:sns:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":", + { + "Fn::GetAtt": [ + "newswiresemailalarmtopicB2906D97", + "TopicName", + ], + }, + ], + ], + }, + ], + "Period": 60, + "Statistic": "Sum", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "Threshold": 0, + "TreatMissingData": "notBreaching", + }, + "Type": "AWS::CloudWatch::Alarm", + }, + "apPollerSecret4DA8E7BD": { + "DeletionPolicy": "Delete", + "Properties": { + "Description": "Secret for the apPoller poller lambda", + "GenerateSecretString": {}, + "Name": "/TEST/editorial-feeds/newswires/apPoller_poller_lambda", + "Tags": [ + { + "Key": "App", + "Value": "newswires", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/newswires", + }, + { + "Key": "Stack", + "Value": "editorial-feeds", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, "editorialfeedsTESTnewswires01BC2EBA": { "DependsOn": [ "InstanceRoleNewswiresDefaultPolicyA474C079", diff --git a/cdk/lib/__snapshots__/riffraff.test.ts.snap b/cdk/lib/__snapshots__/riffraff.test.ts.snap index 6674b39..b17c2fb 100644 --- a/cdk/lib/__snapshots__/riffraff.test.ts.snap +++ b/cdk/lib/__snapshots__/riffraff.test.ts.snap @@ -45,6 +45,20 @@ deployments: fileName: poller-lambdas.zip actions: - uploadLambda + lambda-upload-eu-west-1-editorial-feeds-apPoller_poller_lambda: + type: aws-lambda + stacks: + - editorial-feeds + regions: + - eu-west-1 + app: apPoller_poller_lambda + contentDirectory: poller-lambdas + parameters: + bucketSsmLookup: true + lookupByTags: true + fileName: poller-lambdas.zip + actions: + - uploadLambda asg-upload-eu-west-1-editorial-feeds-newswires: type: autoscaling actions: @@ -79,6 +93,7 @@ deployments: dependencies: - lambda-upload-eu-west-1-editorial-feeds-ingestion-lambda - lambda-upload-eu-west-1-editorial-feeds-reuters_poller_lambda + - lambda-upload-eu-west-1-editorial-feeds-apPoller_poller_lambda - asg-upload-eu-west-1-editorial-feeds-newswires - cfn-eu-west-1-editorial-feeds-wires-feeds lambda-update-eu-west-1-editorial-feeds-ingestion-lambda: @@ -113,6 +128,22 @@ deployments: - updateLambda dependencies: - cfn-eu-west-1-editorial-feeds-newswires + lambda-update-eu-west-1-editorial-feeds-apPoller_poller_lambda: + type: aws-lambda + stacks: + - editorial-feeds + regions: + - eu-west-1 + app: apPoller_poller_lambda + contentDirectory: poller-lambdas + parameters: + bucketSsmLookup: true + lookupByTags: true + fileName: poller-lambdas.zip + actions: + - updateLambda + dependencies: + - cfn-eu-west-1-editorial-feeds-newswires asg-update-eu-west-1-editorial-feeds-newswires: type: autoscaling actions: diff --git a/poller-lambdas/src/index.ts b/poller-lambdas/src/index.ts index 041b8d7..97b9b41 100644 --- a/poller-lambdas/src/index.ts +++ b/poller-lambdas/src/index.ts @@ -5,6 +5,7 @@ import type { PollerId } from '../../shared/pollers'; import { POLLER_LAMBDA_ENV_VAR_KEYS } from '../../shared/pollers'; import { queueNextInvocation, secretsManager, sqs } from './aws'; import { getEnvironmentVariableOrCrash } from './config'; +import { apPoller } from './pollers/ap/apPoller'; import { reutersPoller } from './pollers/reuters/reutersPoller'; import type { HandlerInputSqsPayload, PollFunction } from './types'; import { isFixedFrequencyPollOutput } from './types'; @@ -102,6 +103,7 @@ export const handlers = { // EXAMPLE_long_polling: pollerWrapper(EXAMPLE_long_polling), // EXAMPLE_fixed_frequency: pollerWrapper(EXAMPLE_fixed_frequency), reuters: pollerWrapper(reutersPoller), + apPoller: pollerWrapper(apPoller), } satisfies Record< PollerId, (sqsEvent: HandlerInputSqsPayload) => Promise diff --git a/poller-lambdas/src/pollers/ap/apPoller.ts b/poller-lambdas/src/pollers/ap/apPoller.ts new file mode 100644 index 0000000..50daa79 --- /dev/null +++ b/poller-lambdas/src/pollers/ap/apPoller.ts @@ -0,0 +1,10 @@ +import type { LongPollFunction, PollerInput, SecretValue } from '../../types'; + +export const apPoller = (async (_secret: SecretValue, _input: PollerInput) => { + console.log('AP poller running'); + await new Promise((resolve) => setTimeout(resolve, 15000)); + return { + payloadForIngestionLambda: [], + valueForNextPoll: '', + }; +}) satisfies LongPollFunction; diff --git a/shared/pollers.ts b/shared/pollers.ts index bcf1ed5..92b67a8 100644 --- a/shared/pollers.ts +++ b/shared/pollers.ts @@ -27,4 +27,5 @@ export const POLLERS_CONFIG = { // EXAMPLE_long_polling: {}, // EXAMPLE_fixed_frequency: { idealFrequencyInSeconds: 30 }, reuters: { idealFrequencyInSeconds: 60 }, + apPoller: {}, } as const satisfies Record; // used to generate lambda etc. per agency, with config mapped From 9c89c9721f1af3b68bf38a69514753c52ed307a7 Mon Sep 17 00:00:00 2001 From: Pete F Date: Mon, 13 Jan 2025 12:26:19 +0000 Subject: [PATCH 4/4] Update .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9746cf8..50da8fd 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,6 @@ cdk.out vite.config.d.ts .DS_Store - +.vscode +.bsp +.metals