Questions tagged with AWS CloudFormation

Content language: English

Sort by most recent

Browse through the questions and answers listed below or filter and sort to narrow down your results.

Create Lambda Layer Through Cloud Formation - How to make sure your request credentials have permission to GetObject for bucket?

I am able to deploy a lambda function via CloudFormation, but I wish to deploy it while including a Lambda layer for the requests library. My CloudFormation template contains the following resources: LambdaFunction (gets created successfully) LambdaIAMRole (gets created successfully) LambdaIAMPolicy (gets created successfully) LambdaScheduledRule (gets created successfully) LambdaResourcePolicy (for the LambdaScheduledRule, gets created successfully) LambdaLayer (CREATE_FAILED) Status Reason: Your access has been denied by S3, please make sure your request credentials have permission to GetObject for [bucket] xxxx-nprd-xxxx-xxx-xxxxx-us-east-2/python.zip. S3 Error Code: AccessDenied. S3 Error Message: Access Denied (Service: AWSLambdaInternal; Status Code: 403; Error Code: AccessDeniedException; Request ID: e1d25641-e4cc-47d7-abb4-f0d1b9fb4240; Proxy: null) Here is the code I used to create some of the above resources: "LambdaFunction" : { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": {"Ref" : "CodeSourceBucket" }, "S3Key": "lambdafunction.zip" }, "Environment":{ "Variables" :{ "BUCKET": {"Ref": "xxxx-nprd-xxxx-xxx-xxxxx-us-east-2"}, "BUCKET_PREFIX": {"Ref": "xxx"}, "WEBSITE_URL": {"Ref": "xxx"} } }, "EphemeralStorage" : { "Size" : 512 }, "Handler": "lambda_handler", "Role": {"Fn::GetAtt" : [ "LambdaIAMRole", "Arn" ]}, "Runtime": "python3.9", "FunctionName": { "Fn::Sub": "xxx"}, "Description": "xxx", "Timeout": "90", "MemorySize": 512 } }, "LambdaIAMRole" : { "Type": "AWS::IAM::Role", "Properties": { "RoleName": { "Fn::Sub": "xxx-role"}, "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/" } }, "IAMPolicy": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": { "Fn::Sub": "xxxxxx"}, "PolicyDocument" : { "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ {"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2"}, {"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2/*"} ] }, { "Effect": "Allow", "Action": [ "s3:get*", "s3:put*" ], "Resource": [ {"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2"}, {"xxxx-nprd-xxxx-xxx-xxxxx-us-east-2/*"} ] }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "glue:StartJobRun", "glue:GetJobRun" ], "Resource": "*" }, { "Effect": "Allow", "Action": "lambda:GetLayerVersion", "Resource": "arn:aws:lambda:us-east-x:xxxxxxxxxxxx:request_layer-2-28:1" } ] }, "Roles" : [ {"Ref":"IAMRole"} ] } }, "LambdaLayer": { "Type" : "AWS::Lambda::LayerVersion", "Properties" : { "CompatibleArchitectures" : [ "x86_64" ], "CompatibleRuntimes" : [ "python3.7", "python3.8", "python3.9" ], "Content" : { "S3Bucket": "xxxx-nprd-xxxx-xxx-xxxxx-us-east-2", "S3Key": "python.zip" }, "Description" : "Requests library" } } I was able to manually create my lambda layer for the requests library through the AWS console after creating my lambda function, but I don't know which permissions to include in the template to allow the lambda function to access the Lambda Layer of the python.zip in the S3 bucket (the python.zip contains the requests library). My stack keeps failing to be created because the LambdaLayer resource is failing. I don't see a "lambda layer" policy that I can attach to the role I am using for this lambda function. I also do not see a lambda layer resource policy. I tried to add { "Effect": "Allow", "Action": "lambda:GetLayerVersion", "Resource": "arn:aws:lambda:us-east-x:xxxxxxxxxxxx:layer:request_layer-2-28:1" } to the IAM policy, but it didn't work. Am I supposed to add "Layers" property to the LambdaFunction resource? I also tried to add { "Effect": "Allow", "Action": [ "s3:GetObject" ], to the policy but it did't work. Please help.
1
answers
0
votes
33
views
asked 18 days ago

Bug: Custom Resource deleted due to stack rollback is not given correct PhysicalResourceId

**Description:** I noticed a bug on CloudFormation Custom Resources: when a custom resource creation is cancelled by CloudFormation because another update fails, the custom resource handler receives the wrong `PhysicalResourceId` in the `Delete` event during the `ROLLBACK` phase. **Impact:** This is a problem because, in line with AWS recommendations, the `PhysicalResourceId` is often the ID of a resource in another system, and if the `Delete` handler is not passed the correct ID, then it cannot delete the resource that has already been created. **Reproduction:** To illustrate it I created a simple lambda resource handler that delays for a number of seconds (passed as `Delay` property) and then succeeds or fails (based on the `Succeed` property). With the result it also sends a custom `PhysicalResourceId`. I created a template with three custom resources: 1. Succeeding1: waits 1 second and returns a success response to CloudFormation 2. Failing: waits 5 seconds and returns a failure response to CloudFormation 3. Succeeding2: waits 10 seconds and returns a success response to CloudFormation This gives the following events: ``` Failing CREATE_IN_PROGRESS Succeeding1 CREATE_IN_PROGRESS Succeeding2 CREATE_IN_PROGRESS Succeeding1 CREATE_IN_PROGRESS Resource creation Initiated Succeeding1 CREATE_COMPLETE Failing CREATE_IN_PROGRESS Resource creation Initiated Failing CREATE_FAILED Received response status [FAILED] from custom resource. Succeeding2 CREATE_FAILED Resource creation cancelled TestStack ROLLBACK_IN_PROGRESS The following resource(s) failed to create: [Failing, Succeeding2]. Rollback requested by user. Succeeding2 DELETE_IN_PROGRESS Failing DELETE_IN_PROGRESS Succeeding1 DELETE_IN_PROGRESS Failing DELETE_COMPLETE Succeeding1 DELETE_COMPLETE Succeeding2 DELETE_COMPLETE TestStack ROLLBACK_COMPLETE ``` Note that Succeeding2 fails to create with "Resource creation cancelled" as the reason. Actually, according to the logs for the resource handler, Succeeding2 is successfully created, but when it is deleted it is not sent the `PhysicalResourceId` returned by the `Create` handler. Below are the edited logs from the resource handler. Note that when the resource with logical ID `Success2` is deleted, the handler is passed a `PhysicalResourceId` of `TestStack-Succeeding2-18K7KJ8WCITKL`, even though the `Create` handler sent a value of `success2` to CloudFormation. ``` 2022-11-19T19:25:34.842Z 5c0c23c4-babd-47ea-9a9d-730b669ec1d0 INFO REQUEST Create { RequestType: 'Create', ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', ResponseURL: '****', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328', RequestId: '79864543-61a7-4956-b53b-b97b4d624612', LogicalResourceId: 'Succeeding1', ResourceType: 'Custom::TestResource', ResourceProperties: { ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', Id: 'succeeding1', Delay: '1', Succeed: 'true' } } 2022-11-19T19:25:34.932Z b81e3ec0-a42f-4833-9ac0-d835e1189c64 INFO REQUEST Create { RequestType: 'Create', ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', ResponseURL: '****', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328', RequestId: '2c124be0-10c5-4df1-a34f-d1ba36244b8a', LogicalResourceId: 'Failing', ResourceType: 'Custom::TestResource', ResourceProperties: { ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', Id: 'failing', Delay: '5', Succeed: 'false' } } 2022-11-19T19:25:34.955Z 8b7821bc-731b-4b21-b06e-eb18f93184f2 INFO REQUEST Create { RequestType: 'Create', ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', ResponseURL: '****', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328', RequestId: '138ce7f4-9814-49e4-aa5b-b3723069c91a', LogicalResourceId: 'Succeeding2', ResourceType: 'Custom::TestResource', ResourceProperties: { ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', Id: 'succeeding2', Delay: '10', Succeed: 'true' } } 2022-11-19T19:25:35.844Z 5c0c23c4-babd-47ea-9a9d-730b669ec1d0 INFO RESPONSE { Status: 'SUCCESS', LogicalResourceId: 'Succeeding1', PhysicalResourceId: 'succeeding1', Reason: 'Success: Create', RequestId: '79864543-61a7-4956-b53b-b97b4d624612', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328' } 2022-11-19T19:25:39.963Z b81e3ec0-a42f-4833-9ac0-d835e1189c64 INFO RESPONSE { Status: 'FAILED', LogicalResourceId: 'Failing', PhysicalResourceId: 'failing', Reason: 'Failure: Create', RequestId: '2c124be0-10c5-4df1-a34f-d1ba36244b8a', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328' } 2022-11-19T19:25:44.958Z 8b7821bc-731b-4b21-b06e-eb18f93184f2 INFO RESPONSE { Status: 'SUCCESS', LogicalResourceId: 'Succeeding2', PhysicalResourceId: 'succeeding2', Reason: 'Success: Create', RequestId: '138ce7f4-9814-49e4-aa5b-b3723069c91a', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328' } 2022-11-19T19:25:58.222Z ed3edc75-d612-4795-8a84-37dd9dbab15a INFO REQUEST Delete { RequestType: 'Delete', ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', ResponseURL: '****', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328', RequestId: 'f17b0b04-c777-4fc8-8fcf-c6bafc19fe24', LogicalResourceId: 'Failing', PhysicalResourceId: 'failing', ResourceType: 'Custom::TestResource', ResourceProperties: { ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', Id: 'failing', Delay: '5', Succeed: 'false' } } 2022-11-19T19:25:58.222Z ed3edc75-d612-4795-8a84-37dd9dbab15a INFO RESPONSE { Status: 'SUCCESS', LogicalResourceId: 'Failing', PhysicalResourceId: 'failing', Reason: 'Success: Delete', RequestId: 'f17b0b04-c777-4fc8-8fcf-c6bafc19fe24', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328' } 2022-11-19T19:25:58.338Z 504e4fd4-86c5-4f31-8be1-3da66cfc43e9 INFO REQUEST Delete { RequestType: 'Delete', ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', ResponseURL: '****', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328', RequestId: 'c0b51a3c-278c-4999-8ac7-f48bea2c9378', LogicalResourceId: 'Succeeding1', PhysicalResourceId: 'succeeding1', ResourceType: 'Custom::TestResource', ResourceProperties: { ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', Id: 'succeeding1', Delay: '1', Succeed: 'true' } } 2022-11-19T19:25:58.338Z 504e4fd4-86c5-4f31-8be1-3da66cfc43e9 INFO RESPONSE { Status: 'SUCCESS', LogicalResourceId: 'Succeeding1', PhysicalResourceId: 'succeeding1', Reason: 'Success: Delete', RequestId: 'c0b51a3c-278c-4999-8ac7-f48bea2c9378', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328' } 2022-11-19T19:25:58.517Z 6cd52109-1fb6-403c-9289-6da295829d3c INFO REQUEST Delete { RequestType: 'Delete', ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', ResponseURL: '****', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328', RequestId: '115674d4-53c4-4845-a910-06afb547fd11', LogicalResourceId: 'Succeeding2', PhysicalResourceId: 'TestStack-Succeeding2-18K7KJ8WCITKL', ResourceType: 'Custom::TestResource', ResourceProperties: { ServiceToken: 'arn:aws:lambda:eu-central-1:****:function:TestStack-TestResourceHandler-4uzRRSEzppyu', Id: 'succeeding2', Delay: '10', Succeed: 'true' } } 2022-11-19T19:25:58.517Z 6cd52109-1fb6-403c-9289-6da295829d3c INFO RESPONSE { Status: 'SUCCESS', LogicalResourceId: 'Succeeding2', PhysicalResourceId: 'succeeding2', Reason: 'Success: Delete', RequestId: '115674d4-53c4-4845-a910-06afb547fd11', StackId: 'arn:aws:cloudformation:eu-central-1:****:stack/TestStack/d82bc950-683f-11ed-9330-021d95dc4328' } ```
0
answers
0
votes
16
views
asked 18 days ago

Cloudformation: update stack error Service: ElastiCache, Status Code: 400

Hi, Im using cdk to to create a stack with a redis cluster ```javascript const subnets = vpc.privateSubnets.map(subnet => subnet.subnetId); const subnetGroups = new CfnSubnetGroup( this, 'redisSubnets', { description: 'redis-subnets-${environmentName}', subnetIds: subnets } ); new RedisLogs( this, 'redisClusterLogs', environmentName ); const logsDeliveryConfiguration: CfnCacheCluster.LogDeliveryConfigurationRequestProperty = { logFormat: 'json', logType: 'slow-log', destinationDetails: { cloudWatchLogsDetails: { logGroup: `/redis/${environmentName}` } }, destinationType: 'cloudwatch-logs' }; const clusterProps: CfnCacheClusterProps = { cacheNodeType: 'cache.t3.micro', engine: 'redis', numCacheNodes: 1, autoMinorVersionUpgrade: true, vpcSecurityGroupIds: [securityGroup.securityGroupId], cacheSubnetGroupName: subnetGroups.ref, clusterName: `cluster-${environmentName}`, logDeliveryConfigurations: [logsDeliveryConfiguration], engineVersion: "6.2" }; this.redisCluster = new CfnCacheCluster( this, 'redis-cluster', clusterProps ); this.redisCluster.addDependsOn(subnetGroups) ``` cloudformation fails with this error into resource redisSubnets: ``` Resource handler returned message: "No modifications were requested. (Service: ElastiCache, Status Code: 400, Request ID: xxxxxxxx)" (RequestToken: xxxxxxx, HandlerErrorCode: GeneralServiceException) ``` Im using the same code for develop, certification environments, only in test environment causes this error This stack is in a bigger stack with several nested stacks like ecs, rds and another services, curiously, redis stack not have any changes
1
answers
0
votes
38
views
asked 21 days ago

Silent failure in CloudFormation Lambda VpcConfig

I'm trying to add a VPC to a lambda, via CloudFormation. We're using SAM, so it's a "AWS::Serverless::Function". I have added the VpcConfig section of the CF template as per the docs, but the VPC is never attached to the lambda. No error, successful deploy, but no VPC. I can then add the VPC (and later EFS) config via the console. Drift detection shows no discrepancy between actual and expected, either before or after I manually add the VPC. Deploying again later, using "sam deploy", silently removes the VPC config. Below is a minimal CloudFormation template displaying the behavior. I've tried everything I can think of, including a "DependsOn" clause referencing the VPC and subnets. What am I missing? ``` AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Test template for VPC/Lambda config Resources: MyVPC: Type: AWS::EC2::VPC Properties: CidrBlock: "10.0.0.0/24" EnableDnsHostnames: true EnableDnsSupport: true MyVPCSubnetMaster: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: "10.0.0.0/28" MapPublicIpOnLaunch: true MyVPCSubnetBackup: Type: AWS::EC2::Subnet Properties: VpcId: !Ref MyVPC AvailabilityZone: !Select [ 1, !GetAZs "" ] CidrBlock: "10.0.0.16/28" MapPublicIpOnLaunch: true MyLambda: Type: AWS::Serverless::Function VpcConfig: SecurityGroupIds: - !GetAtt MyVPC.DefaultSecurityGroup SubnetIds: - !GetAtt MyVPCSubnetMaster.SubnetId - !GetAtt MyVPCSubnetBackup.SubnetId Properties: FunctionName: "MyLambda" Runtime: "python3.8" Handler: "index.handler" CodeUri: test/MyLambda ```
2
answers
0
votes
27
views
Eric
asked 21 days ago

Unable to use AWS Parameters and Secrets Lambda Extension

Hello I tried all the steps required to use AWS Parameters and Secrets Lambda Extension such like adding layer and using the X-Aws-Parameters-Secrets-Token in the header but the problem is when I call the request to get the secrets by using AWS Lambda Extension I get the "feign.RetryableException: Connection refused (Connection refused) executing GET http://localhost:2773/secretsmanager/get?secretId=test" problem. Error : Connection refused (Connection refused) executing GET http://localhost:2773/secretsmanager/get?secretId=test" problem. I really do not understand the problem. The token seems fine as well. I used Feign Client to make a GET request to call the secrets by using AWS Lambda Extension . Could you please check the implementation and let me know the problem? ``` //* SecretsAndParametersExtensionAPI class (API class for Feign Client) @Headers({"X-Aws-Parameters-Secrets-Token: {token}"}) public interface SecretsAndParametersExtensionAPI { // TODO move me @RequestLine("GET /secretsmanager/get") @Headers("X-Aws-Parameters-Secrets-Token: {token}") String getSecret(@Param("token") String token, @QueryMap Map<String, Object> queryMap); } // Test class to get Secrets by using AWS Secrets Parameters Lambda Extension @Test public void testSecretsExtension() { String sessionToken = EnvVarCommon.SESSION_TOKEN.get(); System.out.println(sessionToken); try { SecretsAndParametersExtensionAPI secretsAndParametersExtensionAPI = Feign.builder().target(SecretsAndParametersExtensionAPI.class, "http://localhost:2773/"); Map<String, Object> queryMap = new HashMap<>(); queryMap.put("secretId", "test"); String resultFromSecretExtension = secretsAndParametersExtensionAPI.getSecret(sessionToken, queryMap); System.out.println("Result From Secret Extension " + resultFromSecretExtension); log.debug("Request sent to ULH and ULH send request to LAVIN to download profile picture"); } catch (IllegalStateException | JsonSyntaxException exception) { log.error( "Failed to get response from ULH for downloading profile picture for the UserID '{}'", exception); } } //* template.yml file (CloudFormation file for adding Layer) Mappings: RegionToLayerArnMap: us-east-1: "LayerArn": "arn:aws:lambda:us-east-1:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2" us-east-2: "LayerArn": "arn:aws:lambda:us-east-2:590474943231:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2" eu-west-1: "LayerArn": "arn:aws:lambda:eu-west-1:015030872274:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2" eu-west-2: "LayerArn": "arn:aws:lambda:eu-west-2:133256977650:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2" eu-west-3: "LayerArn": "arn:aws:lambda:eu-west-3:780235371811:layer:AWS-Parameters-and-Secrets-Lambda-Extension:2" AlperTestBotLambda: Type: AWS::Serverless::Function Condition: EnableAlperTestbot Properties: Tracing: Active Runtime: java11 Environment: Variables: component: !Ref Component componentShortName: !Ref ComponentShortName version: !Ref Version zone: !Ref Zone tenant: !Ref Tenant testTenant: "test" alperTestQueueName: !Ref AlperTestQueueName aws.sessionToken: !Ref SessionToken Policies: - !Ref SecureParameterAccess - !Ref PurgeSqsPolicyTestQueues EventInvokeConfig: MaximumRetryAttempts: 0 Layers: - !FindInMap [ RegionToLayerArnMap, !Ref "AWS::Region", LayerArn ] ```
1
answers
0
votes
65
views
asked 22 days ago

Custom domain names with the CDK

When using the CDK to create a few services (cloudfront and cognition) I run into a circular problem: I can't create the custom domain in the service until the CNAME record exists, but the CNAME record can't exist yet because I haven't created the service. Example: ``` const domainNames=["my.something.com"]; const certificate = Certificate.fromCertificateArn(stack, "some-id", "arn:aws:acn:us-east-1:........"); const cfconfig = new CloudFrontWebDistribution(stack, "xxx-cloudfront-static", { /* more stuff */ viewerCertificate: ViewerCertificate.fromAcmCertificate(certificate, { aliases: domainNames }) } ); ``` This attempt just gets you this: ``` One or more aliases specified for the distribution includes an incorrectly configured DNS record that points to another CloudFront distribution. You must update the DNS record to correct the problem. For more information, see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-restrictions ``` This happens with Cognito as well. To get around this, I have to omit the custom domain, then give the ops team manual instructions to * Deploy the stack * Go into the console and get the real cloudfront and cognito distribution hostnames * Modify the CNAME records in their DNS (not route 53) * Go back into the console and manually set up the custom domains for cloudfront and cognito Is this just the way it is or am I missing something? It is possible this is just a matter of patience. I destroyed my stack and created it again, but I had old CNAME records now pointing to the new place. I deleted them, but maybe I need to wait longer for them to time out. I had created all the old records with 15 minute TTLs but maybe somebody along the way is not honoring those TTLs.
1
answers
0
votes
9
views
wz2b
asked 25 days ago

How to handle Typescript lambdas using modules embedded in a CDK project

I have a question that's kind of a CloudFormation question but I guess is really a CDK question. My project layout looks like this: ``` work\. ├───cdk.out ├───bin ├───lib ├───node_modules ├───src │ ├───common │ ├───ep │ ├───sites │ └───static ├───package.json ├───tsconfig.json └───test ``` The directories ep, sites, and static are all individual lambdas; the constructor script calls them out like this: ``` entry: path.join(__dirname, "../src/sites/sites.ts"), ``` so that works great. In the package.json I am very careful about what goes into 'dependencies' vs. 'devDependencies' to avoid conflicts and bloat. It occurred to me, though, that some day I might end up with other problems, like conflicts, so I was searching around to see if I can give each individual lambda (ep, sites, static) their own package.json and maybe even tsconfig.json. I found a few things saying it works, but a few others saying it won't. `yarn build` only shows it running tsc once. I think the answer to this is to use [modules](https://javascript.plainenglish.io/how-to-create-multi-module-nodejs-applications-9aff2d73dc17) but because of the way you define an [entry point](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda-nodejs.NodejsFunction.html) (as a path to a single file) I don't get the idea this would work. I'm not sure how to make the lambdas within the CDK project more independent. Do I need to build them into their own, separate projects (outside of the CDK project), bundle them (say with webpack), then have the CDK project reference the build outputs for each? That sounds a little messier, and I like having the entire stack (lambdas and all) in one place. Is there a more self-contained way to do this? Generally speaking, my lambdas are classes. This means that each one has an entry point defined that's just a regular function. If I knew how modules work, could I make each lambda be a module, that's its own class, and have 'entry' point to just a plain typescript function that's part of the CDK project that does something like: ``` import { SpecialHandler } from ../xyz; export async function handleSpecialRequest(request: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> { return new SpecialHandler.handleRequest(request); } ```
1
answers
0
votes
15
views
wz2b
asked a month ago