Open matdumsa opened 2 years ago
Hi, @matdumsa
I tried to create a REST API in us-east-1 with an integration with a Lambda function is eu-west-1. The deployment failed with the following message:
Functions from 'eu-west-1' are not reachable in this region ('us-east-1') (Service: AWSLambda; Status Code: 404; Error Code: ResourceNotFoundException; Request ID: xxx; Proxy: null)
Perhaps this validation hadn't been implemented in CloudFormation when you created the issue? In any case, this validation could be implemented in the CDK as well, improve the feedback loop. Marking this as a p2 feature request.
This issue is still happening, it does not fail but it sets the region as the stack region instead of lambda region
Hello, this issue is still happening with the latest version (2.137.0).
In my case using aws-apigatewayv2
Here my code:
const api = new HttpApiGateway(this, 'api', environment);
const lambdaIntegration = Function.fromFunctionArn(this, 'searchLambda', 'lambdaArn');
api.addIntegration('theintegration', [HttpMethod.GET], lambdaIntegration);
Error:
Functions from 'eu-central-1' are not reachable in this region ('eu-west-2') (Service: Lambda, Stat
us Code: 404
I'll look into this 👍
CloudFormation does indeed fail with the following setup, when the created Lambda is directly passed to the integration:
const app = new App();
const httpEnv = { region: "us-east-1" };
const lambdaEnv = { region: "eu-north-1" };
const httpStack = new Stack(app, "HttpStack", { env: httpEnv });
const httpApi = new HttpApi(httpStack, "HttpApi", {
createDefaultStage: false,
});
const stage = new HttpStage(httpStack, "Stage", {
httpApi,
stageName: "dev",
autoDeploy: true,
});
const lambdaStack = new Stack(app, "LambdaStack", { env: lambdaEnv });
const lambda = new LambdaFunction(lambdaStack, "Lambda", {
functionName: "hello",
code: AssetCode.fromInline(`exports.handler = async (_, { invokedFunctionArn }) => (
{ statusCode: 200, body: "Hello from " + invokedFunctionArn }
);`),
handler: "index.handler",
runtime: Runtime.NODEJS_20_X,
});
httpApi.addRoutes({
path: "/hello",
integration: new HttpLambdaIntegration("hello", lambda),
});
Resource handler returned message: "Functions from 'eu-north-1' are not reachable in this region ('us-east-1')
I am however able to set up a cross-region integration, by importing the Lambda via its ARN and manually setting up the permission:
const httpEnv = { region: "us-east-1" };
const lambdaEnv = { region: "eu-north-1" };
const httpStack = new Stack(app, "HttpStack", { env: httpEnv });
const httpApi = new HttpApi(httpStack, "HttpApi", {
createDefaultStage: false,
});
const stage = new HttpStage(httpStack, "Stage", {
httpApi,
stageName: "dev",
autoDeploy: true,
});
const lambdaStack = new Stack(app, "LambdaStack", { env: lambdaEnv });
const lambda = new LambdaFunction(lambdaStack, "Lambda", {
functionName: "hello",
code: AssetCode.fromInline(`exports.handler = async (_, { invokedFunctionArn }) => (
{ statusCode: 200, body: "Hello from " + invokedFunctionArn }
);`),
handler: "index.handler",
runtime: Runtime.NODEJS_20_X,
});
// Overly broad permissions for the sake of this example
// Please restrain by `sourceArn` in production
lambda.addPermission('permission', {
principal: new ServicePrincipal('apigateway.amazonaws.com'),
});
const importedLambda = LambdaFunction.fromFunctionArn(
httpStack,
"LambdaFromArn",
lambda.functionArn
);
httpApi.addRoutes({
path: "/hello",
integration: new HttpLambdaIntegration("hello", importedLambda),
});
Notice that the API Gateway in us-east-1
is able to invoke the Lambda in eu-north-1
:
$ curl https://<api_id>.execute-api.us-east-1.amazonaws.com/dev/hello
Hello from arn:aws:lambda:eu-north-1:<account_id>:function:hello
This perhaps might even work with cross-account invocations.
I'm not sure how to feel about this. While I agree that this is probably a footgun in most cases, throwing an error here would be restraining a currently deployable and valid pattern.
Thanks @nmussy
I'm unable to replicate your setup without the error, even giving the permission manually:
Lambda stack (eu-central-1)
const readDbLambda = new lambda.Function(this, 'readDbLambdar', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'search.handler', // this is the entry point of your Lambda function
code: lambda.Code.fromAsset(path.join(__dirname, '../src/api/lambda')),
timeout: cdk.Duration.seconds(10),
vpc: defaultVpcEU,
securityGroups: [defaultSecurityGroup],
allowPublicSubnet: true,
vpcSubnets: {
subnetType: SubnetType.PUBLIC,
},
});
readDbLambda.addPermission('permission', {
principal: new ServicePrincipal('apigateway.amazonaws.com'),
});
API GW Stack (eu-west-2)
const api = new HttpApiGateway(this, 'ApiGw', environment);
const searchLambda = Function.fromFunctionArn(this, 'searchLambda', 'arn:aws:lambda:eu-central-1:lambda-arn');
api.addRoutes({
path: '/search',
methods: [HttpMethod.GET],
integration: new HttpLambdaIntegration('search_integration', searchLambda),
});
Resource handler returned message: "Functions from 'eu-central-1' are not reachable in this region ('eu-west-2') (Service: Lambda, Stat
us Code: 404,
I had to create a Lambda function in a different region (eu-central-1) for the following reasons:
While setting up this connection through the AWS console was easy and straightforward, I would much prefer to have all the infrastructure as code. This would automate the process for all my environments and eliminate manual configurations. Would that be something we can get support for in further versions?
I'm not seeing the difference between our two examples. I initially thought it might be your deterministic string value vs. my Fn::Join
preventing CloudFormation from running a check, but my deployment also works if I feed fromFunctionArn
the Lambda ARN directly.
I think the recommended deployment method for multi-account/region apps is through CDK Pipelines, the README should cover what you need to get started. As I mentioned in the comment, my example is definitely not something to reproduce as is, especially the permission.
In regards to the CloudFormation error, I would open an issue in https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/
Sorry I can't be of more help 😅
What is the problem?
In CDK Someone can model an application where an API Gateway lambda integration points to a lambda in a region different than the api gateway endpoint. APIG will even instantiate these, requests won't succeed though.
APIG will fail w/ Execution failed due to configuration error: Functions from 'us-west-2' are not reachable in this region ('us-east-1')
CDK should prevent users from shooting themselves in the foot wherever possible, build time error are easier to catch than runtime error.
Reproduction Steps
What did you expect to happen?
CDK build to fail
What actually happened?
CDK Build Succeeds, CloudFormation synth succeeds
CDK CLI Version
1.131.0 (build 7560c79)
Framework Version
No response
Node.js Version
v12.22.5
OS
OSx
Language
Typescript
Language Version
No response
Other information
No response