Skip to content
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

feat(cfn): implement env controller #1508

Merged
merged 6 commits into from
Nov 3, 2020

Conversation

iamhopaul123
Copy link
Contributor

@iamhopaul123 iamhopaul123 commented Oct 15, 2020

Implement env controller for env upgrade, allowing svc deploy to update env stack to create/delete optional resources (e.g., ALB).

Note that this feature is only available starting from env version v1.0.0.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@iamhopaul123
Copy link
Contributor Author

iamhopaul123 commented Oct 15, 2020

Manual Tests

  • Create an environment. Then deploy a backend service. LB should not be created. Then create an LB service, and the LB should be created. Then delete those services, and LB resources should be removed from env stack.

  • Create an environment. Then deploy two LB services to it simultaneously. Both deployments should succeed. Then delete those two services from the environment, and the LB should be removed.

@efekarakus efekarakus added the do-not-merge Pull requests that mergify shouldn't merge until the requester allows it. label Oct 15, 2020
@iamhopaul123 iamhopaul123 force-pushed the env-upgrade/env-controller branch from 3066f93 to d9edc87 Compare October 15, 2020 18:58
Value:
Fn::ImportValue:
!Sub "${AppName}-${EnvName}-PublicLoadBalancerDNS" {{if .Variables}}{{range $name, $value := .Variables}}
Value: !GetAtt EnvControllerAction.PublicLoadBalancerDNSName{{if .Variables}}{{range $name, $value := .Variables}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will break backend services since the Lambda is not included there!
Mmm this is interesting 🤔

I feel like what we need is a way of telling if an environment variable should exist because the feature is enabled. For example:

{{- if has .RequiredFeatures "ALBWorkloads" }}
- Name: COPILOT_LB_DNS
  Value: !GetAtt EnvControllerAction.PublicLoadBalancerDNSName
{{- end }}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe only display it when it is an LB service?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, we could do that for now. But in the future the LB Web Service pattern will support NLB.
So instead of having http maybe users will specify only udp or tcp and that should still give them a service that is internet-facing. In that scenario we should not create this environment variable.

But yes let's do your suggestion for now! If it's a LBWebService, let's add the environment variable and remove it from the other types that don't force the resource creation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

@@ -168,6 +167,31 @@ Resources:
Action:
- elasticloadbalancing:DescribeRules
Resource: "*"
- PolicyName: "EnvControllerStackUpdate"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm we are increasing the permission scope here! Which would require a security review.

I'm trying to understand how come this prototype worked: efekarakus@66a2c27 without these permission changes. I feel like my prototype shouldn't have worked :O strange!

Copy link
Contributor Author

@iamhopaul123 iamhopaul123 Oct 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you perform those actions without permission 🤔 And looks like the prototype doesn't pass CFN execution role to update the stack, which should fail when updating the environment stack...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok instead of increasing the scope of the other Lambda, let's create a new role:
EnvControllerLambdaRole which has the permissions that you've listed.

Can we try being specific on the resources? For example:

  1. the stack
Resource:  !Sub 'arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AppName}-${EnvName}/*'
  1. the role
Resource:  !Sub 'arn:aws:iam::${AWS::AccountId}:role/${AppName}-${EnvName}-CFNExecutionRole'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on creating a new role otherwise the other lambda scope might be expanded as well. However, I don't get why we want to be specific on the resources? I feel they are about the same since the only stack with both copilot app and env tags are in format of those two. But one benefit for using tags is it is agnostic about the arn format, whereas we are very unlikely to change our copilot tags. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we also need to move the role for auto scaling out right? i'll do that in the next PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slight difference is that if we use only tags, then the role can also update other service stacks in the environment. Whereas specifying the ARN limits it strictly to the environment stack and not to the services.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah got it good point!

@bvtujo bvtujo mentioned this pull request Oct 22, 2020
8 tasks
try {
switch (event.RequestType) {
case "Create":
responseData = await controlEnv(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we increase it to the max 15 mins plz? 🙏

I could see env upgrades taking a while just in case, and we should handle the previous comment above as well

} catch (err) {
if (
!err.message.match(
/^Stack.*is in UPDATE_IN_PROGRESS state and can not be updated/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think they can change it either. OK as long as you validated that this is indeed the error message, I'm fine with it.

Value:
Fn::ImportValue:
!Sub "${AppName}-${EnvName}-PublicLoadBalancerDNS" {{if .Variables}}{{range $name, $value := .Variables}}
Value: !GetAtt EnvControllerAction.PublicLoadBalancerDNSName{{if .Variables}}{{range $name, $value := .Variables}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, we could do that for now. But in the future the LB Web Service pattern will support NLB.
So instead of having http maybe users will specify only udp or tcp and that should still give them a service that is internet-facing. In that scenario we should not create this environment variable.

But yes let's do your suggestion for now! If it's a LBWebService, let's add the environment variable and remove it from the other types that don't force the resource creation.

@@ -168,6 +167,31 @@ Resources:
Action:
- elasticloadbalancing:DescribeRules
Resource: "*"
- PolicyName: "EnvControllerStackUpdate"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok instead of increasing the scope of the other Lambda, let's create a new role:
EnvControllerLambdaRole which has the permissions that you've listed.

Can we try being specific on the resources? For example:

  1. the stack
Resource:  !Sub 'arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AppName}-${EnvName}/*'
  1. the role
Resource:  !Sub 'arn:aws:iam::${AWS::AccountId}:role/${AppName}-${EnvName}-CFNExecutionRole'

@iamhopaul123 iamhopaul123 force-pushed the env-upgrade/env-controller branch from ea73c34 to a135bd1 Compare November 3, 2020 05:58
Copy link
Contributor

@efekarakus efekarakus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! :shipit: just one more request related to the env variable

@iamhopaul123 iamhopaul123 force-pushed the env-upgrade/env-controller branch from 81455a5 to 07320c7 Compare November 3, 2020 22:50
@iamhopaul123 iamhopaul123 removed the do-not-merge Pull requests that mergify shouldn't merge until the requester allows it. label Nov 3, 2020
@iamhopaul123 iamhopaul123 force-pushed the env-upgrade/env-controller branch from 07320c7 to 59a58f7 Compare November 3, 2020 23:08
@mergify mergify bot merged commit e4aeca0 into aws:mainline Nov 3, 2020
mergify bot pushed a commit that referenced this pull request Nov 4, 2020
<!-- Provide summary of changes -->
Address this [comment](#1508 (comment)) left in #1508. Add retry to EnvController when we call `cfn.waitFor()`, so that it won't immediately error out when the request gets throttled.
<!-- Issue number, if available. E.g. "Fixes #31", "Addresses #42, 77" -->

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
thrau pushed a commit to localstack/copilot-cli-local that referenced this pull request Dec 9, 2022
<!-- Provide summary of changes -->
Implement env controller for env upgrade, allowing `svc deploy` to update env stack to create/delete optional resources (e.g., ALB).

Note that this feature is only available starting from env version v1.0.0.
<!-- Issue number, if available. E.g. "Fixes aws#31", "Addresses aws#42, 77" -->

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
thrau pushed a commit to localstack/copilot-cli-local that referenced this pull request Dec 9, 2022
<!-- Provide summary of changes -->
Address this [comment](aws#1508 (comment)) left in aws#1508. Add retry to EnvController when we call `cfn.waitFor()`, so that it won't immediately error out when the request gets throttled.
<!-- Issue number, if available. E.g. "Fixes aws#31", "Addresses aws#42, 77" -->

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants