fix(AWS Lambda): Workaround AWS issue related to alias redeployments

Addresses #7059
This commit is contained in:
Mariusz Nowak 2019-12-20 13:47:29 +01:00
parent eaf9b6117f
commit 3210a94ef9
No known key found for this signature in database
GPG Key ID: B1FBDA8A182B03F2
2 changed files with 86 additions and 0 deletions

View File

@ -163,6 +163,15 @@ module.exports = {
''
)}`;
},
getCodeDeployApplicationLogicalId() {
return 'CodeDeployApplication';
},
getCodeDeployDeploymentGroupLogicalId() {
return 'CodeDeployDeploymentGroup';
},
getCodeDeployRoleLogicalId() {
return 'CodeDeployRole';
},
getLambdaProvisionedConcurrencyAliasLogicalId(functionName) {
return `${this.getNormalizedFunctionName(functionName)}ProvConcLambdaAlias`;
},

View File

@ -542,6 +542,83 @@ class AwsCompileFunctions {
cfTemplate.Resources[
this.provider.naming.getLambdaProvisionedConcurrencyAliasLogicalId(functionName)
] = aliasResource;
// Note: Following setup is a temporary workaround for a known AWS issue of
// "Alias with weights can not be used with Provisioned Concurrency" error being
// thrown when switching version for same alias which has provisioned concurrency configured
// AWS works currently on a fix, and we were informed it'll be released in the near future
const codeDeployApplicationLogicalId = this.provider.naming.getCodeDeployApplicationLogicalId();
const codeDeployDeploymentGroupLogicalId = this.provider.naming.getCodeDeployDeploymentGroupLogicalId();
aliasResource.UpdatePolicy = {
CodeDeployLambdaAliasUpdate: {
ApplicationName: { Ref: codeDeployApplicationLogicalId },
DeploymentGroupName: { Ref: codeDeployDeploymentGroupLogicalId },
},
};
if (!cfTemplate.Resources[codeDeployApplicationLogicalId]) {
const codeDeployApplicationResource = {
Type: 'AWS::CodeDeploy::Application',
Properties: {
ComputePlatform: 'Lambda',
},
};
const codeDeployDeploymentGroupResource = {
Type: 'AWS::CodeDeploy::DeploymentGroup',
Properties: {
ApplicationName: { Ref: codeDeployApplicationLogicalId },
AutoRollbackConfiguration: {
Enabled: true,
Events: [
'DEPLOYMENT_FAILURE',
'DEPLOYMENT_STOP_ON_ALARM',
'DEPLOYMENT_STOP_ON_REQUEST',
],
},
DeploymentConfigName: {
'Fn::Sub': ['CodeDeployDefault.Lambda${ConfigName}', { ConfigName: 'AllAtOnce' }],
},
DeploymentStyle: {
DeploymentType: 'BLUE_GREEN',
DeploymentOption: 'WITH_TRAFFIC_CONTROL',
},
},
};
Object.assign(cfTemplate.Resources, {
[codeDeployApplicationLogicalId]: codeDeployApplicationResource,
[codeDeployDeploymentGroupLogicalId]: codeDeployDeploymentGroupResource,
});
if (this.serverless.service.provider.cfnRole) {
codeDeployDeploymentGroupResource.Properties.ServiceRoleArn = this.serverless.service.provider.cfnRole;
} else {
const codeDeployRoleLogicalId = this.provider.naming.getCodeDeployRoleLogicalId();
const codeDeployRoleResource = {
Type: 'AWS::IAM::Role',
Properties: {
ManagedPolicyArns: [
'arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda',
],
AssumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [
{
Action: ['sts:AssumeRole'],
Effect: 'Allow',
Principal: {
Service: ['codedeploy.amazonaws.com'],
},
},
],
},
},
};
codeDeployDeploymentGroupResource.Properties.ServiceRoleArn = {
'Fn::GetAtt': [codeDeployRoleLogicalId, 'Arn'],
};
cfTemplate.Resources[codeDeployRoleLogicalId] = codeDeployRoleResource;
}
}
});
});
}