Description
Hi folks! This issue is a design proposal for overriding Copilot abstracted resources using the AWS Cloud Development Kit (CDK). The goal is to provide a "break the glass" mechanism to access and configure functionality that is not surfaced by Copilot manifests by leveraging the expressive power of a programming language.
Problem statement
Clients can describe their application configuration with declarative manifest.yml
files. Manifests enable users to define their application in terms of “architecture as code” that gets transformed into AWS CloudFormation (CFN) templates by Copilot. Today, customers have the ability to define additional AWS resources with “addons” CFN templates. However, the resources encapsulated by manifests remain unmodifiable by users. We're looking into providing extension solutions for customers to self-unblock themselves and access the internal layers of Copilot.
This document proposes a user experience for extending manifests with the CDK.
Proposal
-
Copilot will introduce a new command
copilot [noun] override
to create a CDK application that overrides Copilot resources, for example:$ copilot svc override > Which service's resources would you like to override? * frontend * api > Which infrastructure as code tool would you like to use to override "frontend"? * AWS Cloud Development Kit (CDK) * CloudFormation YAML patches > Which programming language would you like to use with the CDK? * Typescript(ts) > Which resources in "frontend" would you like to to override? [ ] DiscoveryService (AWS::ServiceDiscovery::Service) [x] Service (AWS::ECS::Service) [x] PublicNetworkLoadBalancer (AWS::ElasticLoadBalancingV2::LoadBalancer) [ ] TaskDefinition (AWS::ECS::TaskDefinition) ✅ Created a new CDK app under `copilot/frontend/overrides/` to override the resources: . ├── .gitignore ├── .build/ ├── bin/ │ └── override.ts ├── cdk.json ├── package.json ├── stack.ts ├── tsconfig.json └── README.md Copilot did not detect npm installed. > Would you like Copilot to install npm? [Y/n] y ✅ Installed npm v9.1.1 and NodeJS v1.18.2. ✅ Ran `npm install` to install dependencies. > Recommended Actions: 1. Please follow the guide under README.md
The file structure generated by the
override
command is equivalent tocdk init
output. The only additional file created by Copilot is the hidden.build/
directory.In order to simplify onboarding with the CDK, Copilot will assist clients with installing their dependencies. On macOS and Linux, Copilot can install
npm
for customers on their local machine. On Windows, we won't be able to help customers with installingnpm
and will skip to asking them to follow the README instead. Oncenpm
is present, Copilot will runnpm install
to install the dependencies on behalf of the client. -
Clients have to edit only
stack.ts
file in order to implement thetransform*
methods for the selected resources. The following content will be present in the file by default:import * as cdk from 'aws-cdk-lib'; import { aws_elasticloadbalancingv2 as elbv2 } from 'aws-cdk-lib'; import { aws_ecs as ecs } from 'aws-cdk-lib'; export class TransformedStack extends cdk.Stack { constructor (scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); this.template = new cdk.cloudformation_include.CfnInclude(this, 'Template', { templateFile: path.join('.build', 'in.yaml'), }); this.appName = template.getParameter('AppName').valueAsString; this.envName = template.getParameter('EnvName').valueAsString; this.transformService(); this.transformPublicNetworkLoadBalancer(); } // TODO: implement me. transformService() { const service = this.template.getResource("Service") as ecs.CfnService; throw new error("not implemented"); } // TODO: implement me. transformPublicNetworkLoadBalancer() { const publicNetworkLoadBalancer = this.template.getResource("PublicNetworkLoadBalancer") as elbv2.CfnLoadBalancer; throw new error("not implemented"); } }
As can be seen above, Copilot will use the clouformation_include module provided by the CDK to help author transformations. This library is the CDK’s recommendation from their “Import or migrate an existing AWS CloudFormation template” guide. It enables accessing the resources hidden by the manifest as L1 constructs and ensures the CDK retains the resources on synthesis. The
CfnInclude
object is initialized from the.build/in.yaml
CFN template. This is how Copilot and the CDK communicates. Copilot writes the manifest generated CFN template under the.build/
directory, which then gets parsed by thecloudformation_include
library into a CDK construct.
That's it! From this point forward, copilot svc package
or copilot svc deploy
will apply the overrides written in stack.ts
. Under the hood, Copilot will invoke cdk synth
to synthesize the transformed template and use that to deploy to the existing CFN stack.
Feedback
We'd love to hear your feedback on the user experience above:
- Do you see yourself using this feature? (overriding resources with the CDK)
- Does the feature meet your needs?
- If not, can you elaborate on what you'd like to do that can't be done with the above proposal?
Appendix: Sample issues
Every new “capability” feature request can be boiled down to having an override functionality. I’ve captured only a sample of these to test the proposal against.
Link | Description |
---|---|
#4063 | Override nlb configuration to assign elastic IPs to the network load balancer |
#4010 | Assign ReadOnlyRootFS: true to all containers in the task definition by default |
#4005, #3840 | Support for internal NLB for Backend Services. Customers can create the nlb with addons/ but need to wire it by overriding the ECS::Service definition |
#3733 | Allow setting external launch type for ECS tasks |
#3721 | Allow setting VPC flow logs for environments |
#3720 | Turn off assigning public IP addresses for tasks launched in public subnets |
#3594, #1783 | Multiple port support for services behind NLB and ALB |
#3506 | Add additional permissions to the generated environment manager role |
#3504 | Specify additional security groups for the app runner vpc connector |
Metadata
Metadata
Assignees
Type
Projects
Status