我正在使用
serverless
将 lambda 和 APIGateway 部署到 AWS。我发现无服务器在部署期间自动部署了一个随机名称的 lambda。就是附加一些apigateway调用lambda所需的角色策略。这个 lambda 不是我管理的。
例如,当您使用如下 http 端点部署 lambda 时:
handler: xxx
events:
- http:
path: '/v1/order'
method: 'post'
serverless
将部署一个具有自动生成名称的 lambda,该名称在 apigateway 上附加一个角色,以便能够调用此 lambda。我在底部附上了这个 lambda 源代码。 lambda 标记 aws:cloudformation:stack-name
与同一 serverless.yml 中的其他资源位于同一堆栈中。
我正在寻找的是如何在那些自动生成的 lambda 上添加标签。以及如何在这些 lambda 上附加 VPC?
我尝试将标签和 vpc 放在
provider
下,但无服务器不接收它们。
其中一个lambda代码是:
'use strict';
const { awsRequest, wait } = require('../utils');
const { getEnvironment, handlerWrapper } = require('../utils');
async function handler(event, context) {
if (event.RequestType === 'Create') {
return create(event, context);
} else if (event.RequestType === 'Update') {
return update(event, context);
} else if (event.RequestType === 'Delete') {
return remove(event, context);
}
throw new Error(`Unhandled RequestType ${event.RequestType}`);
}
async function create(event, context) {
const { RoleArn } = event.ResourceProperties;
const { Partition: partition, AccountId: accountId, Region: region } = getEnvironment(context);
const assignedRoleArn = (
await awsRequest({ name: 'APIGateway', params: { region } }, 'getAccount')
).cloudwatchRoleArn;
let roleArn = `arn:${partition}:iam::${accountId}:role/serverlessApiGatewayCloudWatchRole`;
if (RoleArn) {
// if there's a roleArn in the Resource Properties, just re-use it here
roleArn = RoleArn;
} else {
// Create an own API Gateway role if the roleArn was not set via Resource Properties
const apiGatewayPushToCloudWatchLogsPolicyArn = `arn:${partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs`;
const roleName = roleArn.slice(roleArn.lastIndexOf('/') + 1);
const attachedPolicies = await (async () => {
try {
return (await awsRequest('IAM', 'listAttachedRolePolicies', { RoleName: roleName }))
.AttachedPolicies;
} catch (error) {
if (error.code === 'NoSuchEntity') {
// Role doesn't exist yet, create;
await awsRequest('IAM', 'createRole', {
AssumeRolePolicyDocument: JSON.stringify({
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Service: ['apigateway.amazonaws.com'],
},
Action: ['sts:AssumeRole'],
},
],
}),
Path: '/',
RoleName: roleName,
});
return [];
}
throw error;
}
})();
if (
!attachedPolicies.some(
(policy) => policy.PolicyArn === apiGatewayPushToCloudWatchLogsPolicyArn
)
) {
await awsRequest('IAM', 'attachRolePolicy', {
PolicyArn: apiGatewayPushToCloudWatchLogsPolicyArn,
RoleName: roleName,
});
}
}
// there's nothing to do if the role is the same
if (roleArn === assignedRoleArn) return null;
const updateAccount = async (counter = 1) => {
try {
await awsRequest({ name: 'APIGateway', params: { region } }, 'updateAccount', {
patchOperations: [
{
op: 'replace',
path: '/cloudwatchRoleArn',
value: roleArn,
},
],
});
} catch (error) {
if (counter < 10) {
// Observed fails with errors marked as non-retryable. Still they're outcome of
// temporary state where just created AWS role is not being ready for use (yet)
await wait(10000);
return updateAccount(++counter);
}
throw error;
}
return null;
};
return updateAccount();
}
function update() {
// No actions
}
function remove() {
// No actions
}
module.exports = {
handler: handlerWrapper(handler, 'CustomResourceApiGatewayAccountCloudWatchRole'),
};
如何在这些 lambda 上附加 VPC?
您可以在 2 个级别上应用 VPC:
provider.vpc
:将 VPC 配置应用于您服务中的所有功能functions.<LambdaName>.vpc
:为特定功能添加VPC配置文档:
伪代码:
# add VPC configuration to a specific function
functions:
hello:
handler: handler.hello
vpc:
securityGroupIds:
- securityGroupId1
- securityGroupId2
subnetIds:
- subnetId1
- subnetId2
# apply VPC configuration to all functions in your service
provider:
name: aws
vpc:
securityGroupIds:
- securityGroupId1
- securityGroupId2
subnetIds:
- subnetId1
- subnetId2
我正在寻找的是如何在那些自动生成的 lambda 上添加标签
Serverless Framework 中有 3 级标签,它们被传递给 CloudFormation。
provider.tags
:应用于 API 和函数的 CloudFormation 标签provider.stackTags
:应用于堆栈和所有支持资源的 CloudFormation 标签。标签应用于其所有子资源,包括自动生成的资源functions.<LambdaName>.tags
:功能特定的标签文档:
伪代码:
provider:
name: aws
tags: # CloudFormation tags to apply to APIs and functions
key: value
stackTags: # CloudFormation tags to apply to the stack and all
key: value
functions:
hello:
handler: handler.hello
tags: # Function specific tags
key: value
重要提示: 在这两种情况下,VPC 或标签配置、继承和覆盖都在起作用。您可以在更高级别定义一个值(
provider.vpc
)并在资源级别覆盖它(functions.<LambdaName>.vpc
)