mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
fixed unit tests for logging resources
This commit is contained in:
parent
5379008ad8
commit
bbdcb429df
@ -15,99 +15,6 @@ module.exports = {
|
||||
'core-cloudformation-template.json')
|
||||
);
|
||||
|
||||
if (typeof this.serverless.service.provider.iamRoleARN !== 'string') {
|
||||
// merge in the iamRoleLambdaTemplate
|
||||
const iamRoleLambdaExecutionTemplate = this.serverless.utils.readFileSync(
|
||||
path.join(this.serverless.config.serverlessPath,
|
||||
'plugins',
|
||||
'aws',
|
||||
'deploy',
|
||||
'lib',
|
||||
'iam-role-lambda-execution-template.json')
|
||||
);
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
iamRoleLambdaExecutionTemplate);
|
||||
|
||||
// merge in the iamPolicyLambdaTemplate
|
||||
const iamPolicyLambdaExecutionTemplate = this.serverless.utils.readFileSync(
|
||||
path.join(this.serverless.config.serverlessPath,
|
||||
'plugins',
|
||||
'aws',
|
||||
'deploy',
|
||||
'lib',
|
||||
'iam-policy-lambda-execution-template.json')
|
||||
);
|
||||
|
||||
// set the necessary variables for the IamPolicyLambda
|
||||
iamPolicyLambdaExecutionTemplate
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyName = `${this.options.stage}-${this.serverless.service.service}-lambda`;
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
iamPolicyLambdaExecutionTemplate);
|
||||
|
||||
this.serverless.service.getAllFunctions().forEach((functionName) => {
|
||||
const functionObject = this.serverless.service.getFunction(functionName);
|
||||
const normalizedFunctionName = functionName[0].toUpperCase() + functionName.substr(1);
|
||||
const logGroupTemplate = `
|
||||
{
|
||||
"${normalizedFunctionName}LogGroup": {
|
||||
"Type" : "AWS::Logs::LogGroup",
|
||||
"Properties" : {
|
||||
"LogGroupName" : "/aws/lambda/${functionObject.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const newLogGroup = JSON.parse(logGroupTemplate);
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
newLogGroup);
|
||||
|
||||
this.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
.push({ 'Fn::GetAtt': [`${normalizedFunctionName}LogGroup`, 'Arn'] });
|
||||
|
||||
this.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[1]
|
||||
.Resource
|
||||
.push({
|
||||
'Fn::Join': [
|
||||
':',
|
||||
[
|
||||
{ 'Fn::GetAtt': [`${normalizedFunctionName}LogGroup`, 'Arn'] },
|
||||
'*',
|
||||
],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
// add custom iam role statements
|
||||
if (this.serverless.service.provider.iamRoleStatements &&
|
||||
this.serverless.service.provider.iamRoleStatements instanceof Array) {
|
||||
this.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement = this.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement.concat(this.serverless.service.provider.iamRoleStatements);
|
||||
}
|
||||
}
|
||||
const bucketName = this.serverless.service.provider.deploymentBucket;
|
||||
|
||||
if (bucketName) {
|
||||
|
||||
@ -36,16 +36,53 @@ module.exports = {
|
||||
.Properties
|
||||
.PolicyName = `${this.options.stage}-${this.serverless.service.service}-lambda`;
|
||||
|
||||
iamPolicyLambdaExecutionTemplate
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource = `arn:aws:logs:${this.options.region}:*:*`;
|
||||
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
iamPolicyLambdaExecutionTemplate);
|
||||
|
||||
this.serverless.service.getAllFunctions().forEach((functionName) => {
|
||||
const functionObject = this.serverless.service.getFunction(functionName);
|
||||
const normalizedFunctionName = functionName[0].toUpperCase() + functionName.substr(1);
|
||||
const logGroupTemplate = `
|
||||
{
|
||||
"${normalizedFunctionName}LogGroup": {
|
||||
"Type" : "AWS::Logs::LogGroup",
|
||||
"Properties" : {
|
||||
"LogGroupName" : "/aws/lambda/${functionObject.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const newLogGroup = JSON.parse(logGroupTemplate);
|
||||
_.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
|
||||
newLogGroup);
|
||||
|
||||
this.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
.push({ 'Fn::GetAtt': [`${normalizedFunctionName}LogGroup`, 'Arn'] });
|
||||
|
||||
this.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[1]
|
||||
.Resource
|
||||
.push({
|
||||
'Fn::Join': [
|
||||
':',
|
||||
[
|
||||
{ 'Fn::GetAtt': [`${normalizedFunctionName}LogGroup`, 'Arn'] },
|
||||
'*',
|
||||
],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// add custom iam role statements
|
||||
if (this.serverless.service.provider.iamRoleStatements &&
|
||||
|
||||
@ -77,201 +77,6 @@ describe('#configureStack', () => {
|
||||
.then(() => {});
|
||||
});
|
||||
|
||||
it('should merge the IamRoleLambdaExecution template into the CloudFormation template', () => {
|
||||
const IamRoleLambdaExecutionTemplate = awsPlugin.serverless.utils.readFileSync(
|
||||
path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'lib',
|
||||
'iam-role-lambda-execution-template.json'
|
||||
)
|
||||
);
|
||||
|
||||
return awsPlugin.configureStack()
|
||||
.then(() => {
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.IamRoleLambdaExecution
|
||||
).to.deep.equal(IamRoleLambdaExecutionTemplate.IamRoleLambdaExecution);
|
||||
});
|
||||
});
|
||||
|
||||
it('should merge IamPolicyLambdaExecution template into the CloudFormation template', () =>
|
||||
awsPlugin.configureStack()
|
||||
.then(() => {
|
||||
// we check for the type here because a deep equality check will error out due to
|
||||
// the updates which are made after the merge (they are tested in a separate test)
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.IamPolicyLambdaExecution.Type
|
||||
).to.deep.equal('AWS::IAM::Policy');
|
||||
})
|
||||
);
|
||||
|
||||
it('should update the necessary variables for the IamPolicyLambdaExecution', () =>
|
||||
awsPlugin.configureStack()
|
||||
.then(() => {
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyName
|
||||
).to.equal(
|
||||
`${
|
||||
awsPlugin.options.stage
|
||||
}-${
|
||||
awsPlugin.serverless.service.service
|
||||
}-lambda`
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
it('should add a CloudWatch LogGroup resource', () => {
|
||||
const normalizedName = `${functionName[0].toUpperCase()}${functionName.substr(1)}LogGroup`;
|
||||
awsPlugin.configureStack();
|
||||
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources[normalizedName]
|
||||
).to.deep.equal(
|
||||
{
|
||||
Type: 'AWS::Logs::LogGroup',
|
||||
Properties: {
|
||||
LogGroupName: `/aws/lambda/${functionName}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should update IamPolicyLambdaExecution with a logging resource for the function', () => {
|
||||
const service = awsPlugin.serverless.service; // avoid 100 char lines below
|
||||
service.functions = {
|
||||
func0: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func0',
|
||||
},
|
||||
func1: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func1',
|
||||
},
|
||||
};
|
||||
const f = service.functions; // avoid 100 char lines below
|
||||
const normalizedNames = [
|
||||
`${f.func0.name[0].toUpperCase()}${f.func0.name.substr(1)}LogGroup`,
|
||||
`${f.func1.name[0].toUpperCase()}${f.func1.name.substr(1)}LogGroup`,
|
||||
];
|
||||
awsPlugin.configureStack();
|
||||
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources[normalizedNames[0]]
|
||||
).to.deep.equal(
|
||||
{
|
||||
Type: 'AWS::Logs::LogGroup',
|
||||
Properties: {
|
||||
LogGroupName: `/aws/lambda/${service.functions.func0.name}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources[normalizedNames[1]]
|
||||
).to.deep.equal(
|
||||
{
|
||||
Type: 'AWS::Logs::LogGroup',
|
||||
Properties: {
|
||||
LogGroupName: `/aws/lambda/${service.functions.func1.name}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should update IamPolicyLambdaExecution with a logging resource for the function', () => {
|
||||
const normalizedName = `${functionName[0].toUpperCase()}${functionName.substr(1)}LogGroup`;
|
||||
awsPlugin.configureStack();
|
||||
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
).to.deep.equal([{ 'Fn::GetAtt': [normalizedName, 'Arn'] }]);
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[1]
|
||||
.Resource
|
||||
).to.deep.equal([{ 'Fn::Join': [':', [{ 'Fn::GetAtt': [normalizedName, 'Arn'] }, '*']] }]);
|
||||
});
|
||||
|
||||
it('should update IamPolicyLambdaExecution with each function\'s logging resources', () => {
|
||||
const service = awsPlugin.serverless.service; // avoid 100 char lines below
|
||||
service.functions = {
|
||||
func0: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func0',
|
||||
},
|
||||
func1: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func1',
|
||||
},
|
||||
};
|
||||
const f = service.functions; // avoid 100 char lines below
|
||||
const normalizedNames = [
|
||||
`${f.func0.name[0].toUpperCase()}${f.func0.name.substr(1)}LogGroup`,
|
||||
`${f.func1.name[0].toUpperCase()}${f.func1.name.substr(1)}LogGroup`,
|
||||
];
|
||||
awsPlugin.configureStack();
|
||||
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
).to.deep.equal(
|
||||
[
|
||||
{ 'Fn::GetAtt': [normalizedNames[0], 'Arn'] },
|
||||
{ 'Fn::GetAtt': [normalizedNames[1], 'Arn'] },
|
||||
]
|
||||
);
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[1]
|
||||
.Resource
|
||||
).to.deep.equal(
|
||||
[
|
||||
{ 'Fn::Join': [':', [{ 'Fn::GetAtt': [normalizedNames[0], 'Arn'] }, '*']] },
|
||||
{ 'Fn::Join': [':', [{ 'Fn::GetAtt': [normalizedNames[1], 'Arn'] }, '*']] },
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it('should add custom IAM policy statements', () => {
|
||||
awsPlugin.serverless.service.provider.name = 'aws';
|
||||
awsPlugin.serverless.service.provider.iamRoleStatements = [
|
||||
{
|
||||
Effect: 'Allow',
|
||||
Action: [
|
||||
'something:SomethingElse',
|
||||
],
|
||||
Resource: 'some:aws:arn:xxx:*:*',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
return awsPlugin.configureStack()
|
||||
.then(() => {
|
||||
expect(awsPlugin.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.IamPolicyLambdaExecution.Properties.PolicyDocument.Statement[2]
|
||||
).to.deep.equal(awsPlugin.serverless.service.provider.iamRoleStatements[0]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should use a custom bucket if specified', () => {
|
||||
const bucketName = 'com.serverless.deploys';
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ const AwsDeploy = require('../');
|
||||
describe('#mergeIamTemplates()', () => {
|
||||
let awsDeploy;
|
||||
let serverless;
|
||||
const functionName = 'test';
|
||||
|
||||
beforeEach(() => {
|
||||
serverless = new Serverless();
|
||||
@ -21,6 +22,14 @@ describe('#mergeIamTemplates()', () => {
|
||||
awsDeploy.serverless.service.provider.compiledCloudFormationTemplate = {
|
||||
Resources: {},
|
||||
};
|
||||
awsDeploy.serverless.service.service = 'new-service';
|
||||
awsDeploy.serverless.service.functions = {
|
||||
[functionName]: {
|
||||
name: 'test',
|
||||
artifact: 'test.zip',
|
||||
handler: 'handler.hello',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@ -42,8 +51,8 @@ describe('#mergeIamTemplates()', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should merge IamPolicyLambdaExecution template into the CloudFormation template', () =>
|
||||
awsDeploy.mergeIamTemplates()
|
||||
it('should merge IamPolicyLambdaExecution template into the CloudFormation template',
|
||||
() => awsDeploy.mergeIamTemplates()
|
||||
.then(() => {
|
||||
// we check for the type here because a deep equality check will error out due to
|
||||
// the updates which are made after the merge (they are tested in a separate test)
|
||||
@ -53,8 +62,8 @@ describe('#mergeIamTemplates()', () => {
|
||||
})
|
||||
);
|
||||
|
||||
it('should update the necessary variables for the IamPolicyLambdaExecution', () =>
|
||||
awsDeploy.mergeIamTemplates()
|
||||
it('should update the necessary variables for the IamPolicyLambdaExecution',
|
||||
() => awsDeploy.mergeIamTemplates()
|
||||
.then(() => {
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
@ -68,15 +77,6 @@ describe('#mergeIamTemplates()', () => {
|
||||
awsDeploy.serverless.service.service
|
||||
}-lambda`
|
||||
);
|
||||
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
).to.equal(`arn:aws:logs:${awsDeploy.options.region}:*:*`);
|
||||
})
|
||||
);
|
||||
|
||||
@ -96,7 +96,7 @@ describe('#mergeIamTemplates()', () => {
|
||||
return awsDeploy.mergeIamTemplates()
|
||||
.then(() => {
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources.IamPolicyLambdaExecution.Properties.PolicyDocument.Statement[1]
|
||||
.Resources.IamPolicyLambdaExecution.Properties.PolicyDocument.Statement[2]
|
||||
).to.deep.equal(awsDeploy.serverless.service.provider.iamRoleStatements[0]);
|
||||
});
|
||||
});
|
||||
@ -121,4 +121,130 @@ describe('#mergeIamTemplates()', () => {
|
||||
.Resources.IamRoleLambdaExecution
|
||||
).to.not.exist);
|
||||
});
|
||||
|
||||
it('should add a CloudWatch LogGroup resource', () => {
|
||||
const normalizedName = `${functionName[0].toUpperCase()}${functionName.substr(1)}LogGroup`;
|
||||
return awsDeploy.mergeIamTemplates().then(() => {
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources[normalizedName]
|
||||
).to.deep.equal(
|
||||
{
|
||||
Type: 'AWS::Logs::LogGroup',
|
||||
Properties: {
|
||||
LogGroupName: `/aws/lambda/${functionName}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should update IamPolicyLambdaExecution with a logging resource for the function', () => {
|
||||
const service = awsDeploy.serverless.service; // avoid 100 char lines below
|
||||
service.functions = {
|
||||
func0: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func0',
|
||||
},
|
||||
func1: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func1',
|
||||
},
|
||||
};
|
||||
const f = service.functions; // avoid 100 char lines below
|
||||
const normalizedNames = [
|
||||
`${f.func0.name[0].toUpperCase()}${f.func0.name.substr(1)}LogGroup`,
|
||||
`${f.func1.name[0].toUpperCase()}${f.func1.name.substr(1)}LogGroup`,
|
||||
];
|
||||
return awsDeploy.mergeIamTemplates().then(() => {
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources[normalizedNames[0]]
|
||||
).to.deep.equal(
|
||||
{
|
||||
Type: 'AWS::Logs::LogGroup',
|
||||
Properties: {
|
||||
LogGroupName: `/aws/lambda/${service.functions.func0.name}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources[normalizedNames[1]]
|
||||
).to.deep.equal(
|
||||
{
|
||||
Type: 'AWS::Logs::LogGroup',
|
||||
Properties: {
|
||||
LogGroupName: `/aws/lambda/${service.functions.func1.name}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should update IamPolicyLambdaExecution with a logging resource for the function', () => {
|
||||
const normalizedName = `${functionName[0].toUpperCase()}${functionName.substr(1)}LogGroup`;
|
||||
return awsDeploy.mergeIamTemplates().then(() => {
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
).to.deep.equal([{ 'Fn::GetAtt': [normalizedName, 'Arn'] }]);
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[1]
|
||||
.Resource
|
||||
).to.deep.equal([{ 'Fn::Join': [':', [{ 'Fn::GetAtt': [normalizedName, 'Arn'] }, '*']] }]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should update IamPolicyLambdaExecution with each function\'s logging resources', () => {
|
||||
const service = awsDeploy.serverless.service; // avoid 100 char lines below
|
||||
service.functions = {
|
||||
func0: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func0',
|
||||
},
|
||||
func1: {
|
||||
handler: 'func.function.handler',
|
||||
name: 'func1',
|
||||
},
|
||||
};
|
||||
const f = service.functions; // avoid 100 char lines below
|
||||
const normalizedNames = [
|
||||
`${f.func0.name[0].toUpperCase()}${f.func0.name.substr(1)}LogGroup`,
|
||||
`${f.func1.name[0].toUpperCase()}${f.func1.name.substr(1)}LogGroup`,
|
||||
];
|
||||
return awsDeploy.mergeIamTemplates().then(() => {
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[0]
|
||||
.Resource
|
||||
).to.deep.equal(
|
||||
[
|
||||
{ 'Fn::GetAtt': [normalizedNames[0], 'Arn'] },
|
||||
{ 'Fn::GetAtt': [normalizedNames[1], 'Arn'] },
|
||||
]
|
||||
);
|
||||
expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
|
||||
.Resources
|
||||
.IamPolicyLambdaExecution
|
||||
.Properties
|
||||
.PolicyDocument
|
||||
.Statement[1]
|
||||
.Resource
|
||||
).to.deep.equal(
|
||||
[
|
||||
{ 'Fn::Join': [':', [{ 'Fn::GetAtt': [normalizedNames[0], 'Arn'] }, '*']] },
|
||||
{ 'Fn::Join': [':', [{ 'Fn::GetAtt': [normalizedNames[1], 'Arn'] }, '*']] },
|
||||
]
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user