-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve IAM role statements, policies and principals internal handling and resolution #8511
Changes from all commits
de0a382
cab0679
00c061e
e0b72e4
dc86185
91a58ee
97d0f4a
bf8f0eb
b7a871c
43e321a
31be8c1
34b66dd
27302e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2525,6 +2525,118 @@ describe('AwsCompileFunctions #2', () => { | |
}); | ||
}); | ||
|
||
describe('IamConfig object tests', async () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Concerning tests, as indicated in main issue description, let's not put any effort in updating them in current shape. Technically we're just refactoring internals, and result CloudFormation template should remain same (at least it should produce very same effect) To avoid tests breaking on internal changes, we need to refactor affected tests to I've outlined on how to do that for two tests files that you're trying to update here Check: #8523 and #8524 Until those are addressed, we need assume that this PR cannot be merged (but it doesn't stop us from finalizing this refactor - it just cannot be properly validated until tests are refactored). After we refactor all affected tests, the only test changes that may be wanted in scope of this PR is moving some of the tests to other files, or improving the coverage, that's it, but I would decide that once we have all tests refactored, and functionality in this PR ready |
||
let serverless; | ||
let awsNaming; | ||
|
||
before(async () => { | ||
({ serverless, awsNaming } = await runServerless({ | ||
fixture: 'function', | ||
configExt: { | ||
functions: { | ||
custom: { name: 'custom-name', handler: 'index.handler' }, | ||
canonical: { | ||
handler: 'index.handler', | ||
vpc: { securityGroupIds: ['securityGroupId1'], subnetIds: ['subnetId1'] }, | ||
}, | ||
}, | ||
}, | ||
cliArgs: ['package'], | ||
})); | ||
}); | ||
|
||
it('Should create iamConfig object', () => { | ||
serverless.service.getAllFunctions().forEach(functionName => { | ||
const functionObject = serverless.service.getFunction(functionName); | ||
expect(functionObject.iamConfig).to.exist; | ||
}); | ||
}); | ||
|
||
it('should add log policies to iamConfig object', () => { | ||
const logStatementsTemplate = [ | ||
{ | ||
Effect: 'Allow', | ||
Action: ['logs:CreateLogStream', 'logs:CreateLogGroup'], | ||
Resource: [], | ||
}, | ||
{ | ||
Effect: 'Allow', | ||
Action: ['logs:PutLogEvents'], | ||
Resource: [], | ||
}, | ||
]; | ||
|
||
const canonicalFunctionNamePrefix = `${serverless.service.service}-${serverless | ||
.getProvider('aws') | ||
.getStage()}`; | ||
const logGroupsPrefix = awsNaming.getLogGroupName(canonicalFunctionNamePrefix); | ||
|
||
serverless.service.getAllFunctions().forEach(functionName => { | ||
const functionObject = serverless.service.getFunction(functionName); | ||
const resolvedFunctionName = functionObject.name; | ||
|
||
// if function has canonical name | ||
if (!resolvedFunctionName || resolvedFunctionName.startsWith(canonicalFunctionNamePrefix)) { | ||
logStatementsTemplate[0].Resource.push({ | ||
'Fn::Sub': | ||
'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}' + | ||
`:log-group:${logGroupsPrefix}*:*`, | ||
}); | ||
|
||
logStatementsTemplate[1].Resource.push({ | ||
'Fn::Sub': | ||
'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}' + | ||
`:log-group:${logGroupsPrefix}*:*:*`, | ||
}); | ||
} else { | ||
// if function has custom name resolution | ||
const customFunctionNameLogGroupsPrefix = awsNaming.getLogGroupName(resolvedFunctionName); | ||
|
||
logStatementsTemplate[0].Resource.push({ | ||
'Fn::Sub': | ||
'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}' + | ||
`:log-group:${customFunctionNameLogGroupsPrefix}:*`, | ||
}); | ||
|
||
logStatementsTemplate[1].Resource.push({ | ||
'Fn::Sub': | ||
'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}' + | ||
`:log-group:${customFunctionNameLogGroupsPrefix}:*:*`, | ||
}); | ||
} | ||
|
||
const statements = functionObject.iamConfig.policyStatements; | ||
|
||
expect(statements).to.deep.include(logStatementsTemplate[0]); | ||
expect(statements).to.deep.include(logStatementsTemplate[1]); | ||
|
||
logStatementsTemplate[0].Resource = []; | ||
logStatementsTemplate[1].Resource = []; | ||
}); | ||
}); | ||
|
||
it('should add vpc managed policies to iamConfig object when vpc config is present', () => { | ||
const vpcManagedPolicy = { | ||
'Fn::Join': [ | ||
'', | ||
[ | ||
'arn:', | ||
{ Ref: 'AWS::Partition' }, | ||
':iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole', | ||
], | ||
], | ||
}; | ||
|
||
serverless.service.getAllFunctions().forEach(functionName => { | ||
const functionObject = serverless.service.getFunction(functionName); | ||
|
||
if (!_.isEmpty(functionObject.vpc)) { | ||
expect(functionObject.iamConfig.managedPolicies).to.deep.include(vpcManagedPolicy); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
describe('when using fileSystemConfig', () => { | ||
const arn = | ||
'arn:aws:elasticfilesystem:us-east-1:111111111111:access-point/fsap-a1a1a1a1a1a1a1a1a'; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ideally should be initialized in
mergeIamTemplates.js
(so we have this configuration setup upfront, while this plugin is complied as some next item in order afaik)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @medikoo . I tried this before but it was giving me multiple errors (~63), which is why I opted for including this code in
functions/index.js
instead. I put the code inmergeIamTemplates.js
in my latest commit so you can take a look. Maybe there's something I'm missing?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What errors specifically? Is this about failing tests, if so in that case, please list all test files - we need to refactor them to
runServelress
variant.Technically this upgrade should not require any tests to be written or updated, and just work, but for that we need to have many tests refactored to new approach
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The errors only occur when the code to create the
functions[].iamConfig
objects are included inmergeIamTemplates.js
instead offunctions/index.js
. All the errors are fromindex.test.js
and they all say this:so I think it means the iamConfig object hasn't been created yet. That's why I opted for including this code in
functions/index.js
instead since I thinkmergeIamTemplates.js
hasn't yet run by the timefunctions/index.js
is executed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that we need to address #8523. After having that, there won't be such error.
Again, let's not get blocked, or have our implementation influenced by failing (for wrong reason) tests. We have very bad tests in many places, and all that fail should be simply refactored (as proposed in above issue)