-
Notifications
You must be signed in to change notification settings - Fork 4k
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
fix(codebuild): cannot use immutable roles for Project #5608
Conversation
Immutably imported `Role`s could not be used for CodeBuild `Project`s, because they would create a policy but be unable to attach it to the Role. That leaves an unattached Policy, which is invalid. Fix this by making `Policy` objects only render to an `AWS::IAM::Policy` resource if they actually have any effect. It is perfectly allowed to create new unattached Policy objects, or have empty Policy objects. Only if and when they actually need to mutate the policy of an IAM identity will they render themselves to the CloudFormation template. Being able to abstract away these kinds of concerns is exactly the value of a higher-level programming model. To allow for the rare cases where an empty Policy object would be considered a programming error, we still have the flag `mustCreate` which triggers the legacy behavior of alwyas creating the `AWS::IAM::Policy` resource which must have a statement and be attached to an identity.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
private get shouldExist() { | ||
return this.mustCreate || this.referenceTaken || (!this.document.isEmpty && this.isAttached); | ||
} |
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.
since this is temporal (i.e. only relevant after the tree has been fully initialized) and used only in one place, I think this code should just be part of prepare
to avoid accidentally using it in the future from the wrong context.
* | ||
* It is not an error if a child with the given name does not exist. | ||
*/ | ||
public removeChild(childName: string) { |
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.
Maybe rename to tryRemoveChild
to indicate it won't throw, and return a boolean indicating if the child was actually removed or not.
I am a bit worried by potential abuse of this API. Maybe we can make it a bit safer and only allow this during "prepare" somehow? What do you think? Can you please also mark this as @experimental
?
This also resolves #1408
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.
I'm not too worried about misuse. The methods on node
are pretty much "plumbing sticking out" anyway, not sure they're part of people's day-to-day operations with the API.
I would hope that people venturing there will be aware they're messing with internals which can do what they want, or have unintentional effects they themselves will be responsible for cleaning up. Not sure that limiting to prepare()
is necessary.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
* | ||
* @default false | ||
*/ | ||
readonly mustCreate?: boolean; |
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.
I still don't love this name... I proposed changing it to lazy?: boolean
in the previous PR, but I'm also open to other suggestions 🙂
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.
forceResource?
mustExist?
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.
I feel "lazy" is usually used to communicate something else.
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.
Maybe just force
?
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.
I was considering force
, slightly on the fence but I also don't have a better alternative. I can do force
.
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.
forceReify? forceRender?
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
protected validate(): string[] { | ||
const result = new Array<string>(); | ||
|
||
// validate that the policy document is not empty | ||
if (this.document.isEmpty) { | ||
result.push('Policy is empty. You must add statements to the policy'); | ||
if (this.force) { | ||
result.push('Policy created with mustCreate=true is empty. You must add statements to the policy'); |
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.
References old property name.
result.push('Policy created with mustCreate=true is empty. You must add statements to the policy'); | ||
} | ||
if (!this.force && this.referenceTaken) { | ||
result.push('Policy name has been read of empty policy. You must add statements to the policy so it can exist.'); |
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.
See #5569 (comment)
result.push(`Policy created with mustCreate=true must be attached to at least one principal: user, group or role`); | ||
} | ||
if (!this.force && this.referenceTaken) { | ||
result.push('Policy name has been read of unattached policy. Attach to at least one principal: user, group or role.'); |
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.
See here: #5569 (comment)
result.push(`Policy must be attached to at least one principal: user, group or role`); | ||
if (!this.isAttached) { | ||
if (this.force) { | ||
result.push(`Policy created with mustCreate=true must be attached to at least one principal: user, group or role`); |
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.
References old property name.
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request is now being automatically merged. |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request is now being automatically merged. |
Commit Message
fix(codebuild): cannot use immutable roles for Project
Immutably imported
Role
s could not be used for CodeBuildProject
s, because they would create a policy but be unableto attach it to the Role. That leaves an unattached Policy,
which is invalid.
Fix this by making
Policy
objects only render to anAWS::IAM::Policy
resource if they actually have any effect. It is perfectly allowed to
create new unattached Policy objects, or have empty Policy objects.
Only if and when they actually need to mutate the policy of an IAM
identity will they render themselves to the CloudFormation template.
Being able to abstract away these kinds of concerns is exactly the value
of a higher-level programming model.
To allow for the rare cases where an empty Policy object would be
considered a programming error, we still have the flag
mustCreate
which triggers the legacy behavior of alwyas creating the
AWS::IAM::Policy
resource which must have a statement and beattached to an identity.
Fixes #1408.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license