|
| 1 | +Auto Create ECR Repos in Guided Deploy |
| 2 | +==================================== |
| 3 | + |
| 4 | + |
| 5 | +What is the problem? |
| 6 | +-------------------- |
| 7 | + |
| 8 | +With the release of Lambda Container Images Support in SAM CLI, customers today have to specify a ECR Repo URI location where images will need to be uploaded by SAM CLI after having been built. This means that customers need to have pre-created resources ready (in this case ECR repos) to go, so that they can supply them during the deploy process. This introduces friction and break in the seamless workflow that `sam deploy --guided` normally offers, with customers having to figure out how to create a ECR repo and how to find correct ECR URI to specify. |
| 9 | + |
| 10 | +Current flow for deploying a template with image based function: |
| 11 | + |
| 12 | +1. Create ECR repo: `aws ecr create-repository --repository-name myecr_repo` |
| 13 | + |
| 14 | +2. Deploy with SAM CLI guided: `sam deploy --guided` |
| 15 | + |
| 16 | +3. Specify image repo: `Image Repository for HelloWorldFunction []: 12345.dkr.ecr.us-west-2.amazonaws.com/helloworldfunctionrepo` |
| 17 | + |
| 18 | +What will be changed? |
| 19 | +--------------------- |
| 20 | + |
| 21 | +When deploying with guided, SAM CLI will prompt the option to auto create ECR repos for image based functions. |
| 22 | +The auto created ECR repos will reside in a companion stack that gets deployed along with the actual stack. |
| 23 | + |
| 24 | +During each guided deploy, the functions and repos will be synced. |
| 25 | + |
| 26 | + |
| 27 | +Each function without an image repo specified will have a corresponding repo created in the companion stack. |
| 28 | +If a function is deleted from the template and has an auto created image repo previously associated with it, the auto created image repo will also be removed. |
| 29 | + |
| 30 | + |
| 31 | + |
| 32 | +There will be an escape hatch to use non SAM CLI managed repos by specifying `--image-repositories` or changing `samconfig.toml`. |
| 33 | + |
| 34 | +Success criteria for the change |
| 35 | +------------------------------- |
| 36 | + |
| 37 | +* No context switching from SAM CLI to creating resources using other tools. |
| 38 | + |
| 39 | +Out-of-Scope |
| 40 | +------------ |
| 41 | + |
| 42 | +* SAM CLI will not manage lifecycles, creation and deletion, of the auto created resources outside of SAM CLI. For auto created image repos, modifications to the functions throught other means like console will not modify the associated image repo until the next deployment with SAM CLI. |
| 43 | +* Auto create repo only concerns about guided experience. Repos are assumed to be provided in CI/CD situations. However the option --resolve-image-repos will be added for auto creating repos without going through guided. |
| 44 | + |
| 45 | +User Experience Walkthrough |
| 46 | +--------------------------- |
| 47 | + |
| 48 | +`sam deploy --guided` |
| 49 | + |
| 50 | +**Creating New Repos** |
| 51 | + |
| 52 | + |
| 53 | +``` |
| 54 | +====================== |
| 55 | +Looking for config file [samconfig.toml] : Not found |
| 56 | +
|
| 57 | +Setting default arguments for 'sam deploy' |
| 58 | +========================================= |
| 59 | +Stack Name [sam-app]: images-app |
| 60 | +AWS Region [us-east-1]: us-east-2 |
| 61 | +#Shows you resources changes to be deployed and require a 'Y' to initiate deploy |
| 62 | +Confirm changes before deploy [y/N]: y |
| 63 | +#SAM needs permission to be able to create roles to connect to the resources in your template |
| 64 | +Allow SAM CLI IAM role creation [Y/n]: y |
| 65 | +Save arguments to configuration file [Y/n]: y |
| 66 | +SAM configuration file [samconfig.toml]: |
| 67 | +SAM configuration environment [default]: |
| 68 | +Looking for resources needed for deployment: |
| 69 | + S3 bucket: Found! (aws-sam-cli-managed-default-samclisourcebucket-abcdef) |
| 70 | + Image repositories: Not found. |
| 71 | + #Managed repositories will be deleted when their functions are removed from the template and deployed |
| 72 | + Create managed ECR repositories for all functions? [Y/n]: Y |
| 73 | + Creating the required resources... |
| 74 | + Successfully created resources for deployment! |
| 75 | +
|
| 76 | +Successfully saved arguments to config file! |
| 77 | + #Running 'sam deploy' for future deployments will use the parameters saved above. |
| 78 | + #The above parameters can be changed by modifying samconfig.toml |
| 79 | + #Learn more about samconfig.toml syntax at |
| 80 | + #https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html |
| 81 | +
|
| 82 | +Uploading to abcdefg/7dd33d96eafcae1086a1356df982d38e 539284 / 539284.0 (100.00%) |
| 83 | +
|
| 84 | +Deploying with the following values |
| 85 | +=================================== |
| 86 | +Stack name : test-stack |
| 87 | +Region : us-east-2 |
| 88 | +Confirm changeset : True |
| 89 | +Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-abcdef |
| 90 | +Image repositories : [ |
| 91 | + {“helloWorldFunction1”:"12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction1-abcde"}, |
| 92 | + {“helloWorldFunction2”:"12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction2-abcde"}, |
| 93 | + {“helloWorldFunction3”:"12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction3-abcde”} |
| 94 | +] |
| 95 | +Capabilities : ["CAPABILITY_IAM"] |
| 96 | +Parameter overrides : {} |
| 97 | +Signing profiles : {} |
| 98 | +
|
| 99 | +Initiating deployment |
| 100 | +``` |
| 101 | + |
| 102 | +**Deleting Unreferenced Repos** |
| 103 | + |
| 104 | +``` |
| 105 | +Configuring SAM deploy |
| 106 | +====================== |
| 107 | +
|
| 108 | + Looking for config file [samconfig.toml] : Found |
| 109 | + Reading default arguments : Success |
| 110 | +
|
| 111 | + Setting default arguments for 'sam deploy' |
| 112 | + ========================================= |
| 113 | + Stack Name [test-stack]: |
| 114 | + AWS Region [us-east-2]: |
| 115 | + #Shows you resources changes to be deployed and require a 'Y' to initiate deploy |
| 116 | + Confirm changes before deploy [Y/n]: y |
| 117 | + #SAM needs permission to be able to create roles to connect to the resources in your template |
| 118 | + Allow SAM CLI IAM role creation [Y/n]: y |
| 119 | + HelloWorldFunction4 may not have authorization defined, Is this okay? [y/N]: y |
| 120 | + HelloWorldFunction5 may not have authorization defined, Is this okay? [y/N]: y |
| 121 | + Save arguments to configuration file [Y/n]: y |
| 122 | + SAM configuration file [samconfig.toml]: |
| 123 | + SAM configuration environment [default]: |
| 124 | +
|
| 125 | + Looking for resources needed for deployment: Found! |
| 126 | +
|
| 127 | + Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-abcdef |
| 128 | + A different default S3 bucket can be set in samconfig.toml |
| 129 | +
|
| 130 | + Image repositories: Not found. |
| 131 | + #Managed repositories will be deleted when their functions are removed from the template and deployed |
| 132 | + Create managed ECR repositories for all functions? [Y/n]: y |
| 133 | + Checking for unreferenced ECR repositories to clean-up: 2 found |
| 134 | + 12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction1-abcde |
| 135 | + 12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction2-abcde |
| 136 | + Delete the unreferenced repositories listed above when deploying? [y/N]: y |
| 137 | +
|
| 138 | + helloworldfunction4:python3.8-v1 to be pushed to 12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction4-abcde:helloworldfunction4-7bfff073dfcf-python3.8-v1 |
| 139 | + helloworldfunction5:python3.8-v1 to be pushed to 12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction5-abcde:helloworldfunction5-7bfff073dfcf-python3.8-v1 |
| 140 | +
|
| 141 | +
|
| 142 | + Saved arguments to config file |
| 143 | + Running 'sam deploy' for future deployments will use the parameters saved above. |
| 144 | + The above parameters can be changed by modifying samconfig.toml |
| 145 | + Learn more about samconfig.toml syntax at |
| 146 | + https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html |
| 147 | +
|
| 148 | +
|
| 149 | + Deploying with following values |
| 150 | + =============================== |
| 151 | + Stack name : auto-ecr-guided-test |
| 152 | + Region : us-west-2 |
| 153 | + Confirm changeset : True |
| 154 | + Deployment image repository : |
| 155 | + { |
| 156 | + "HelloWorldFunction3": "12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction3-abcde", |
| 157 | + "HelloWorldFunction4": "12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction4-abcde", |
| 158 | + "HelloWorldFunction5": "12345.dkr.ecr.us-east-2.amazonaws.com/helloworldfunction5-abcde" |
| 159 | + } |
| 160 | + Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-abcde |
| 161 | + Capabilities : ["CAPABILITY_IAM"] |
| 162 | + Parameter overrides : {} |
| 163 | + Signing Profiles : {} |
| 164 | +``` |
| 165 | + |
| 166 | +--resolve-image-repos |
| 167 | +--------------------------- |
| 168 | +This new option will have the exact behavior as running guided with confirmation for all image repo related prompts. |
| 169 | + |
| 170 | +To be more specific, this option will: |
| 171 | +1. Create image repos for functions are not linked to image repos with the `--image-repositories` |
| 172 | +2. Delete auto created image repos that do not have functions associated with them anymore |
| 173 | + |
| 174 | +Destructive operations are done for the following reasons: |
| 175 | +1. This will keep a consistent behavior as the guided. In guided, SAM CLI will abort deployment if deletion of auto created image repos is denied. |
| 176 | +2. For UX, this will avoid image repos and functions mapping to an invalid state where orphaned image repos exist. For this case, we will also need to track which repos should be kept and makes the sync less robust. |
| 177 | +3. From security perspective, keeping old image repos will increase the impact radius of an information leakage. A customer might expect a sensitive image repo will be deleted as soon as the function itself is also removed like the guided experience. |
| 178 | + |
| 179 | +Implementation |
| 180 | +============== |
| 181 | + |
| 182 | +CLI Changes |
| 183 | +----------- |
| 184 | + |
| 185 | +* Add new prompt for guided deploy. |
| 186 | + * `Create managed ECR repositories for all functions? [Y/n]: y` |
| 187 | +* Add `--resolve-image-repos` to non-guided deploy |
| 188 | + |
| 189 | + |
| 190 | +### Breaking Change |
| 191 | + |
| 192 | +* Not a breaking change. |
| 193 | + |
| 194 | +Design |
| 195 | +------ |
| 196 | + |
| 197 | +**Companion Stack Naming Scheme** |
| 198 | +``` |
| 199 | +#Escaped StackName with only common accpetable characters |
| 200 | +escaped_stack_name = re.sub(r"[^a-z0-9]", "", stack_name.lower()) |
| 201 | +#Escaped LambdaName with only common accpetable characters |
| 202 | +escaped_lambda_logical_id = re.sub(r"[^a-z0-9]", "", lambda_logical_id.lower()) |
| 203 | +#MD5 of the original StackName. |
| 204 | +stack_md5 = hash.str_checksum(stack_name) |
| 205 | +#MD5 of the original LambdaName |
| 206 | +function_md5 = hash.str_checksum(lambda_logical_id) |
| 207 | +
|
| 208 | +#MD5 is used to avoid two having the same escaped name with different Lambda Functions |
| 209 | +#For example: Helloworld and HELLO-WORLD |
| 210 | +repo_logical_id = |
| 211 | + lambda_logical_id [:52] + function_md5 [:8] + "Repo" |
| 212 | + #52 + 8 + 4 = 64 max char |
| 213 | + |
| 214 | +repo_name = |
| 215 | + escaped_stack_name + stack_md5[:8] + "/" + escaped_lambda_logical_id + function_md5[:8] + "repo" |
| 216 | + #128 + 8 + 1 + 64 + 8 + 4 = 213 max char |
| 217 | + |
| 218 | +companion_stack_name = |
| 219 | + stack_name[:104] + "-" + stack_md5[:8] + "-" + "CompanionStack" |
| 220 | + #104 + 1 + 8 + 1 + 14 = 128 max char |
| 221 | + |
| 222 | +repo_output_logical_id = |
| 223 | + lambda_logical_id[:52] + function_md5 [:8] + "Out" |
| 224 | + #52 + 8 + 3 = 63 max char |
| 225 | +
|
| 226 | +Exmaple: |
| 227 | + Input: |
| 228 | + Customer Stack Name: Hello-World-Stack |
| 229 | + Function 1 Logical ID: TestFunction01 |
| 230 | + Function 2 Logical ID: AnotherTestFunction02 |
| 231 | + Output: |
| 232 | + Companion Stack Name: Hello-World-Stack-925976eb-CompanionStack |
| 233 | + Function 1 Repo Logical ID: TestFunction0150919004Repo |
| 234 | + Function 1 Repo Name: helloworldstack925976eb/testfunction0150919004repo |
| 235 | + Function 2 Repo Logical ID: AnotherTestFunction025c2cfd8cRepo |
| 236 | + Function 2 Repo Name: helloworldstack925976eb/anothertestfunction025c2cfd8crepo |
| 237 | +``` |
| 238 | + |
| 239 | +**Companion Stack Structure** |
| 240 | +``` |
| 241 | +AWSTemplateFormatVersion : '2010-09-09' |
| 242 | +Transform: AWS::Serverless-2016-10-31 |
| 243 | +Description: AWS SAM CLI Managed ECR Repo Stack |
| 244 | +Metadata: |
| 245 | + SamCliInfo: 1.18.0 |
| 246 | + CompanionStackname: Hello-World-Stack-925976eb-CompanionStack |
| 247 | +
|
| 248 | +Resources: |
| 249 | +
|
| 250 | + TestFunction0150919004Repo: |
| 251 | + Type: AWS::ECR::Repository |
| 252 | + Properties: |
| 253 | + RepositoryName: helloworldstack925976eb/testfunction0150919004repo |
| 254 | + Tags: |
| 255 | + - Key: ManagedStackSource |
| 256 | + Value: AwsSamCli |
| 257 | + - Key: AwsSamCliCompanionStack |
| 258 | + Value: Hello-World-Stack-925976eb-CompanionStack |
| 259 | +
|
| 260 | + RepositoryPolicyText: |
| 261 | + Version: "2012-10-17" |
| 262 | + Statement: |
| 263 | + - |
| 264 | + Sid: AllowLambdaSLR |
| 265 | + Effect: Allow |
| 266 | + Principal: |
| 267 | + Service: |
| 268 | + - "lambda.amazonaws.com" |
| 269 | + Action: |
| 270 | + - "ecr:GetDownloadUrlForLayer" |
| 271 | + - "ecr:GetRepositoryPolicy" |
| 272 | + - "ecr:BatchGetImage" |
| 273 | +
|
| 274 | + AnotherTestFunction025c2cfd8cRepo: |
| 275 | + Type: AWS::ECR::Repository |
| 276 | + Properties: |
| 277 | + RepositoryName: helloworldstack925976eb/anothertestfunction025c2cfd8crepo |
| 278 | + Tags: |
| 279 | + - Key: ManagedStackSource |
| 280 | + Value: AwsSamCli |
| 281 | + - Key: AwsSamCliCompanionStack |
| 282 | + Value: Hello-World-Stack-925976eb-CompanionStack |
| 283 | +
|
| 284 | + RepositoryPolicyText: |
| 285 | + Version: "2012-10-17" |
| 286 | + Statement: |
| 287 | + - |
| 288 | + Sid: AllowLambdaSLR |
| 289 | + Effect: Allow |
| 290 | + Principal: |
| 291 | + Service: |
| 292 | + - "lambda.amazonaws.com" |
| 293 | + Action: |
| 294 | + - "ecr:GetDownloadUrlForLayer" |
| 295 | + - "ecr:GetRepositoryPolicy" |
| 296 | + - "ecr:BatchGetImage" |
| 297 | +
|
| 298 | +Outputs: |
| 299 | +
|
| 300 | + None: |
| 301 | + Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/${TestFunction0150919004Repo} |
| 302 | +
|
| 303 | + None: |
| 304 | + Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/${AnotherTestFunction025c2cfd8cRepo} |
| 305 | +``` |
| 306 | + |
| 307 | +Documentation Changes |
| 308 | +===================== |
| 309 | +* New option `--resolve-image-repos`. This option will auto create/delete repos without the needs of going through guided experience. |
| 310 | + |
| 311 | +Open Issues |
| 312 | +============ |
| 313 | +https://github.com/aws/aws-sam-cli/issues/2447 |
| 314 | + |
| 315 | +Task Breakdown |
| 316 | +============== |
| 317 | + |
| 318 | +- \[x\] Send a Pull Request with this design document |
| 319 | +- \[ \] Build Companion Stack Manager |
| 320 | +- \[ \] Change Deploy CLI |
| 321 | +- \[ \] Unit tests |
| 322 | +- \[ \] Functional Tests |
| 323 | +- \[ \] Integration tests |
| 324 | +- \[ \] Update documentation |
0 commit comments