Skip to content

Commit 851a8ae

Browse files
committed
update docs
1 parent 20c91b9 commit 851a8ae

File tree

2 files changed

+56
-58
lines changed

2 files changed

+56
-58
lines changed

README.md

Lines changed: 55 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,23 @@ Terraform module pattern to build a standard Lambda API.
55

66
#### [New to Terraform Modules at BYU?](https://github.com/byu-oit/terraform-documentation)
77

8-
This module uses CodeDeploy to deploy a Lambda behind an ALB.
8+
This module deploys a Lambda behind an ALB.
9+
10+
## CodeDeploy Option
11+
12+
Optionally, CodeDeploy can be used to perform "blue/green" deployments of new versions of the Lambda.
13+
14+
Before switching production traffic to the new Lambda, CodeDeploy runs Postman tests. This is done by:
915

10-
Before switching production traffic to the new Lambda, CodeDeploy runs Postman tests.
11-
This is done by:
1216
* Having all production traffic (port `443`) sent to the Lambda version considered `live`
1317
* Creating and deploying the new untested Lambda version to `$LATEST`
1418
* Invoking a separate "test" Lambda that runs Postman tests
1519
- These tests run against the port specified by `codedeploy_test_listener_port`, which corresponds to `$LATEST`
16-
* If the tests pass, we give the alias `live` to the now-tested `$LATEST` version of the Lambda
20+
* If the tests pass, we move the `live` alias to the now-tested `$LATEST` version of the Lambda
21+
22+
Note: If you do not specify `use_codedeploy = true`, the above process will not apply. Instead, the `live` alias will be updated directly by `terraform apply`.
23+
24+
Also Note: CodePipeline and CodeDeploy cannot be used together to deploy a Lambda. If you are using CodePipeline, you cannot specify `use_codedeploy = true`. CodeDeploy works fine with other pipelining tools (e.g. GitHub Actions).
1725

1826
## Usage
1927
```hcl
@@ -32,6 +40,7 @@ module "lambda_api" {
3240
private_subnet_ids = module.acs.private_subnet_ids
3341
role_permissions_boundary_arn = module.acs.role_permissions_boundary.arn
3442
codedeploy_test_listener_port = 4443
43+
use_codedeploy = true
3544
3645
codedeploy_lifecycle_hooks = {
3746
BeforeAllowTraffic = aws_lambda_function.test_lambda.function_name
@@ -40,24 +49,22 @@ module "lambda_api" {
4049
}
4150
```
4251
## Created Resources
43-
##### TODO fix this section (copy pasta from standard fargate)
4452

45-
* ECS Cluster
46-
* ECS Service
53+
* Lambda Function
54+
* with IAM role and policies
4755
* with security group
48-
* ECS Task Definition
49-
* with IAM role
56+
* with "live" alias (for blue-green deployment)
5057
* CloudWatch Log Group
5158
* ALB
5259
* with security group
53-
* 2 Target Groups (for blue-green deployment)
60+
* with listeners and target groups
61+
* 80 (redirects to 443)
62+
* 443 (HTTPS forwards to "live")
63+
* test_listener_port (HTTPS forwards to "latest")
5464
* CodeDeploy App
5565
* with IAM role
5666
* CodeDeploy Group
5767
* DNS A-Record
58-
* AutoScaling Target
59-
* AutoScaling Policies (one for stepping up and one for stepping down)
60-
* CloudWatch Metric Alarms (one for stepping up and one for stepping down)
6168

6269
## Requirements
6370
* Terraform version 0.12.21 or greater
@@ -110,13 +117,20 @@ This module will create a CloudWatch log group named `/aws/lambda/<app_name>-<en
110117
For instance with the [above example](#usage) the logs could be found in the CloudWatch log group: `aws/lambda/my-lambda-dev`.
111118

112119
## Outputs
113-
##### TODO fill out this section
114120

115121
| Name | Type | Description |
116122
| --- | --- | --- |
123+
| lambda | [object](https://www.terraform.io/docs/providers/aws/r/lambda_function.html#argument-reference) | The Lambda that handles API requests |
124+
| lambda_security_group | [object](https://www.terraform.io/docs/providers/aws/r/security_group.html#argument-reference) | Controls what the Lambda can access |
125+
| lambda_live_alias | [object](https://www.terraform.io/docs/providers/aws/r/lambda_alias.html#argument-reference) | Controls which version of the Lambda receives "live" traffic |
126+
| codedeploy_deployment_group | [object](https://www.terraform.io/docs/providers/aws/r/codedeploy_deployment_group.html#argument-reference) | The CodeDeploy deployment group object. |
127+
| codedeploy_appspec_json_file | string | Filename of the generated appspec.json file |
128+
| alb | [object](https://www.terraform.io/docs/providers/aws/r/lb.html#argument-reference) | The Application Load Balancer (ALB) object |
129+
| alb_security_group | [object](https://www.terraform.io/docs/providers/aws/r/security_group.html#argument-reference) | The ALB's security group object |
130+
| dns_record | [object](https://www.terraform.io/docs/providers/aws/r/route53_record.html#argument-reference) | The DNS A-record mapped to the ALB |
131+
| cloudwatch_log_group | [object](https://www.terraform.io/docs/providers/aws/r/cloudwatch_log_group.html#argument-reference) | The log group for the Lambda's logs |
117132

118133
#### appspec
119-
##### TODO fix this section (copy pasta from standard fargate)
120134

121135
This module also creates a JSON file in the project directory: `appspec.json` used to initiate a CodeDeploy Deployment.
122136

@@ -125,15 +139,14 @@ Here's an example appspec.json file this creates:
125139
{
126140
"Resources": [
127141
{
128-
"TargetService": {
142+
"apiLambdaFunction": {
129143
"Properties": {
130-
"LoadBalancerInfo": {
131-
"ContainerName": "example",
132-
"ContainerPort": 8000
133-
},
134-
"TaskDefinition": "arn:aws:ecs:us-west-2:123456789123:task-definition/example-api-def:2"
144+
"Alias": "live",
145+
"CurrentVersion": "6",
146+
"Name": "my-lambda-codedeploy-dev",
147+
"TargetVersion": "6"
135148
},
136-
"Type": "AWS::ECS::SERVICE"
149+
"Type": "AWS::Lambda::Function"
137150
}
138151
}
139152
],
@@ -145,32 +158,19 @@ And example with [lifecycle hooks](#codedeploy_lifecycle_hooks):
145158
{
146159
"Hooks": [
147160
{
148-
"BeforeInstall": null
149-
},
150-
{
151-
"AfterInstall": "AfterInstallHookFunctionName"
152-
},
153-
{
154-
"AfterAllowTestTraffic": "AfterAllowTestTrafficHookFunctionName"
155-
},
156-
{
157-
"BeforeAllowTraffic": null
158-
},
159-
{
160-
"AfterAllowTraffic": null
161+
"BeforeAllowTraffic": "my-lambda-deploy-test"
161162
}
162163
],
163164
"Resources": [
164165
{
165-
"TargetService": {
166+
"apiLambdaFunction": {
166167
"Properties": {
167-
"LoadBalancerInfo": {
168-
"ContainerName": "example",
169-
"ContainerPort": 8000
170-
},
171-
"TaskDefinition": "arn:aws:ecs:us-west-2:123456789123:task-definition/example-api-def:2"
168+
"Alias": "live",
169+
"CurrentVersion": "6",
170+
"Name": "my-lambda-codedeploy-dev",
171+
"TargetVersion": "6"
172172
},
173-
"Type": "AWS::ECS::SERVICE"
173+
"Type": "AWS::Lambda::Function"
174174
}
175175
}
176176
],
@@ -179,23 +179,22 @@ And example with [lifecycle hooks](#codedeploy_lifecycle_hooks):
179179
```
180180

181181
## CodeDeploy Blue-Green Deployment
182-
##### TODO fix this section (copy pasta from standard fargate)
183182

184-
This module creates a blue-green deployment process with CodeDeploy. If a `codedeploy_test_listener_port` is provided
185-
this module will create an ALB listener that will allow public traffic from that port to the running lambda.
183+
If `use_codedeploy = true` is specified, this module creates a blue-green deployment process with CodeDeploy. If a `codedeploy_test_listener_port` is provided this module will create an ALB listener that will allow public traffic from that port to the running lambda.
186184

187185
When a CodeDeploy deployment is initiated (either via a pipeline or manually) CodeDeploy will:
188-
1. call lambda function defined for `BeforeInstall` hook
189-
2. attempt to create a new set of tasks (called the replacement set) with the new task definition etc. in the unused ALB Target Group
190-
3. call lambda function defined for `AfterInstall` hook
191-
4. associate the test listener (if defined) to the new target group
192-
5. call lambda function defined for `AfterAllowTestTraffic` hook
193-
6. call lambda function defined for `BeforeAllowTraffic` hook
194-
7. associate the production listener to the new target group
195-
8. call lambda function defined for `AfterAllowTraffic` hook
196-
9. wait for the `codedeploy_termination_wait_time` in minutes before destroying the original task set (this is useful if you need to manually rollback)
197-
198-
At any step (except step #1) the deployment can rollback (either manually or by the lambda functions in the lifecycle hooks or if there was an error trying to actually deploy)
186+
1. call lambda function defined for `BeforeAllowTraffic` hook
187+
2. associate the "live" alias "TargetVersion"
188+
3. call lambda function defined for `AfterAllowTraffic` hook
189+
190+
At any step the deployment can rollback (either manually or by the lambda functions in the lifecycle hooks or if there was an error trying to actually deploy)
191+
192+
If manual rollback is needed after the deployment has completed, that can be done in the Lambda Console:
193+
1. Select your Lambda Function.
194+
2. Select a function alias (aka. "Qualifier")
195+
3. Click the "Edit alias" button
196+
4. Select the version you want to roll back to
197+
5. Click "Save"
199198

200199
##### TODO add diagrams to explain the blue-green deployment process
201200

main.tf

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ resource "aws_lambda_permission" "with_tst_lb" {
156156

157157
resource "aws_alb_target_group_attachment" "live_attachment" {
158158
target_group_arn = aws_alb_target_group.tg.arn
159-
target_id = var.use_codedeploy ? aws_lambda_alias.live_codedeploy[0].arn : aws_lambda_alias.live[0].arn
159+
target_id = var.use_codedeploy ? aws_lambda_alias.live_codedeploy[0].arn : aws_lambda_alias.live[0].arn #Live
160160
depends_on = [aws_lambda_permission.with_lb]
161161
}
162162

@@ -223,7 +223,6 @@ resource "aws_iam_role_policy_attachment" "lambda_policy_attach" {
223223
role = aws_iam_role.iam_for_lambda.name
224224
}
225225

226-
# TODO: the SG fails to destroy because the lambda's ENI is still using it.
227226
resource "aws_security_group" "lambda_sg" {
228227
name = "${local.long_name}-lambda-sg"
229228
description = "Controls access to the Lambda"

0 commit comments

Comments
 (0)