Skip to content

Commit f4920a9

Browse files
aahelcthain
andauthored
Add support for pushing consul-lambda-registrator public image to p… (#82)
* Add support for pushing `consul-lambda-registrator` public image to private ecr repo through terraform * fmt tf * minor readme fix * addressed review comments * added fixes and fixed acceptance test * updated aws provider version * updated aws provider version * added force_delete to aws_ecr_repository in test * fmt tf * Update modules/lambda-registrator/main.tf Co-authored-by: Chris Thain <[email protected]> * Update modules/lambda-registrator/main.tf Co-authored-by: Chris Thain <[email protected]> * Update modules/lambda-registrator/variables.tf Co-authored-by: Chris Thain <[email protected]> * grouped data sources together * added review changes * add some fixes * test fixes * minor test fix * added default "" to test ecr_image_uri * fmt tf * Update modules/lambda-registrator/main.tf Co-authored-by: Chris Thain <[email protected]> * added validation test * fixed tf fmt and made validation test parallel * removed validation test from basic test * added test case to validate when privateEcrReponame is set * updated enable_auto_publish_ecr_image var description * fixed tf fmt * Update modules/lambda-registrator/variables.tf Co-authored-by: Chris Thain <[email protected]> * changed consul_image version in basic_test --------- Co-authored-by: Chris Thain <[email protected]>
1 parent 5b828b9 commit f4920a9

File tree

18 files changed

+295
-29
lines changed

18 files changed

+295
-29
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ FEATURES
44
* Add support for storing parameter values greater than 4 KB. The `lambda-registrator` module and source code have been updated to accept a configurable value for the [SSM parameter tier](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-advanced-parameters.html). This allows users to choose if they want to use the `Advanced` tier feature. Charges apply for the `Advanved` tier so if the tier is not expressly set to `Advanced`, then the `Standard` tier will be used. Using the `Advanced` tier allows for parameter values up to 8 KB. The Lambda-registrator Terraform module can be configured using the new `consul_extension_data_tier` variable.
55
[[GH-78]](https://github.com/hashicorp/terraform-aws-consul-lambda/pull/78)
66

7+
* Add support for pushing `consul-lambda-registrator` public image to private ecr repo through terraform.
8+
[[GH-82]](https://github.com/hashicorp/terraform-aws-consul-lambda/pull/82)
9+
710
## 0.1.0-beta4 (Apr 28, 2023)
811

912
IMPROVEMENTS

examples/lambda/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ This example Terraform workspace will use the zip package to deploy the `consul-
110110
add it to the `lambda-app-2` function so that it can call services within the Consul service mesh.
111111

112112
```shell
113-
curl -o consul-lambda-extension.zip https://releases.hashicorp.com/consul-lambda-extension/${VERSION}/consul-lambda-extension_${VERSION}_linux_amd64.zip
113+
curl -o consul-lambda-extension.zip "https://releases.hashicorp.com/consul-lambda-extension/${VERSION}/consul-lambda-extension_${VERSION}_linux_amd64.zip"
114114
```
115115

116116
## Build the example Lambda function

examples/lambda/lambda/variables.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ variable "invocation_mode" {
9494
default = "SYNCHRONOUS"
9595
validation {
9696
condition = contains(["SYNCHRONOUS", "ASYNCHRONOUS"], var.invocation_mode)
97-
error_message = "invocation_mode must be one of SYNCHRONOUS or ASYNCHRONOUS"
97+
error_message = "Variable invocation_mode must be one of SYNCHRONOUS or ASYNCHRONOUS."
9898
}
9999
}
100100

examples/lambda/providers.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ terraform {
55
required_providers {
66
aws = {
77
source = "hashicorp/aws"
8-
version = "4.25.0"
8+
version = "4.67.0"
99
}
1010
random = {
1111
source = "hashicorp/random"

examples/lambda/variables.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,14 @@ variable "consul_lambda_extension_arn" {
3838
type = string
3939
default = ""
4040
}
41+
42+
variable "consul_lambda_registrator_image" {
43+
description = "The Lambda registrator image to use. Must be provided as <registry/repository:tag>"
44+
type = string
45+
default = "public.ecr.aws/hashicorp/consul-lambda-registrator:0.1.0-beta4"
46+
47+
validation {
48+
condition = can(regex("^[a-zA-Z0-9_.-]+/[a-z0-9_.-]+/[a-z0-9_.-]+:[a-zA-Z0-9_.-]+$", var.consul_lambda_registrator_image))
49+
error_message = "Image format of 'consul_lambda_registrator_image' is invalid. It should be in the format 'registry/repository:tag'."
50+
}
51+
}

modules/lambda-registrator/main.tf

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# Copyright (c) HashiCorp, Inc.
22
# SPDX-License-Identifier: MPL-2.0
33

4+
terraform {
5+
required_providers {
6+
docker = {
7+
source = "kreuzwerker/docker"
8+
version = "3.0.2"
9+
}
10+
11+
}
12+
}
13+
414
locals {
515
on_vpc = length(var.subnet_ids) > 0 && length(var.security_group_ids) > 0
616
vpc_config = local.on_vpc ? [{
@@ -9,6 +19,25 @@ locals {
919
}] : []
1020
cron_key = "${var.name}-cron"
1121
lambda_events_key = "${var.name}-lambda_events"
22+
image_parts = split(":", var.consul_lambda_registrator_image)
23+
image_tag = local.image_parts[1]
24+
ecr_repo_name = var.private_ecr_repo_name == "" ? "consul-lambda-registrator-${random_id.repo_id.hex}" : var.private_ecr_repo_name
25+
# generated_ecr_image_uri is used when we want to automatically push the public image to a private ecr repo using docker.
26+
generated_ecr_image_uri = "${data.aws_caller_identity.current_identity.account_id}.dkr.ecr.${data.aws_region.current_region.name}.amazonaws.com/${local.ecr_repo_name}:${local.image_tag}"
27+
}
28+
29+
# Equivalent of aws ecr get-login
30+
data "aws_ecr_authorization_token" "ecr_auth" {}
31+
data "aws_region" "current_region" {}
32+
data "aws_caller_identity" "current_identity" {}
33+
34+
provider "docker" {
35+
host = var.docker_host
36+
registry_auth {
37+
username = data.aws_ecr_authorization_token.ecr_auth.user_name
38+
password = data.aws_ecr_authorization_token.ecr_auth.password
39+
address = "${data.aws_caller_identity.current_identity.account_id}.dkr.ecr.${data.aws_region.current_region.name}.amazonaws.com"
40+
}
1241
}
1342

1443
resource "aws_iam_role" "registration" {
@@ -126,9 +155,35 @@ resource "aws_iam_role_policy_attachment" "lambda_logs" {
126155
role = aws_iam_role.registration.name
127156
policy_arn = aws_iam_policy.policy.arn
128157
}
158+
resource "random_id" "repo_id" {
159+
byte_length = 4
160+
}
161+
162+
resource "aws_ecr_repository" "lambda-registrator" {
163+
count = var.enable_auto_publish_ecr_image ? 1 : 0
164+
name = local.ecr_repo_name
165+
force_delete = true
166+
}
167+
168+
resource "docker_image" "lambda_registrator" {
169+
count = var.enable_auto_publish_ecr_image ? 1 : 0
170+
name = var.consul_lambda_registrator_image
171+
}
172+
173+
resource "docker_tag" "lambda_registrator_tag" {
174+
count = var.enable_auto_publish_ecr_image ? 1 : 0
175+
source_image = docker_image.lambda_registrator[count.index].name
176+
target_image = local.generated_ecr_image_uri
177+
}
178+
179+
resource "docker_registry_image" "push_image" {
180+
count = var.enable_auto_publish_ecr_image ? 1 : 0
181+
name = docker_tag.lambda_registrator_tag[count.index].target_image
182+
keep_remotely = true
183+
}
129184

130185
resource "aws_lambda_function" "registration" {
131-
image_uri = var.ecr_image_uri
186+
image_uri = var.enable_auto_publish_ecr_image ? local.generated_ecr_image_uri : var.ecr_image_uri
132187
package_type = "Image"
133188
function_name = var.name
134189
role = aws_iam_role.registration.arn
@@ -168,6 +223,9 @@ resource "aws_lambda_function" "registration" {
168223
security_group_ids = vpc_config.value["security_group_ids"]
169224
}
170225
}
226+
depends_on = [
227+
docker_registry_image.push_image
228+
]
171229
}
172230

173231
module "eventbridge" {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
locals {
2+
require_ecr_image_uri_or_enable_auto_publish_ecr_image_set = var.ecr_image_uri == "" && var.enable_auto_publish_ecr_image == false ? file("ERROR: either ecr_image_uri or enable_auto_publish_ecr_image must be set") : null
3+
}

modules/lambda-registrator/variables.tf

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ variable "ecr_image_uri" {
8484
repository or configuring pull through cache rules (https://docs.aws.amazon.com/AmazonECR/latest/userguide/pull-through-cache.html).
8585
EOT
8686
type = string
87+
default = ""
8788
}
8889

8990
variable "sync_frequency_in_minutes" {
@@ -109,3 +110,39 @@ variable "tags" {
109110
type = map(string)
110111
default = {}
111112
}
113+
114+
variable "private_ecr_repo_name" {
115+
description = "The name of the repository to republish the ECR image if one exists. If no name is passed, it is assumed that no repository exists and one needs to be created."
116+
type = string
117+
default = ""
118+
}
119+
120+
variable "consul_lambda_registrator_image" {
121+
description = "The Lambda registrator image to use. Must be provided as <registry/repository:tag>"
122+
type = string
123+
default = "public.ecr.aws/hashicorp/consul-lambda-registrator:0.1.0-beta4"
124+
125+
validation {
126+
condition = can(regex("^[a-zA-Z0-9_.-]+/[a-z0-9_.-]+/[a-z0-9_.-]+:[a-zA-Z0-9_.-]+$", var.consul_lambda_registrator_image))
127+
error_message = "Image format of 'consul_lambda_registrator_image' is invalid. It must be in the format 'registry/repository:tag'."
128+
}
129+
}
130+
131+
variable "docker_host" {
132+
description = "The docker socket for your system"
133+
type = string
134+
default = "unix:///var/run/docker.sock"
135+
}
136+
137+
variable "enable_auto_publish_ecr_image" {
138+
description = <<-EOT
139+
Enables automatic publishing of a public Lambda Registrator image to a private ECR repository via Docker.
140+
When enable_auto_publish_ecr_image is set to true, the image defined by consul_lambda_registrator_image will be pulled and published to a private ECR repository. If private_ecr_repo_name is set, that name will be used to create the private ECR repository, otherwise the default name, consul-lambda-registrator-<random-suffix>, will be used
141+
142+
You must set at least one of ecr_image_uri or enable_auto_publish_ecr_image. If enable_auto_publish_ecr_image is set to true then ecr_image_uri is ignored.
143+
144+
Using this method to automatically pull the public image and push it to a private ECR repository requires access to the docker command in the local environment.
145+
EOT
146+
type = bool
147+
default = false
148+
}

test/acceptance/setup-terraform/ecr.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ locals {
88
}
99

1010
resource "aws_ecr_repository" "lambda-registrator" {
11-
name = local.ecr_repository_name
11+
name = local.ecr_repository_name
12+
force_delete = true
1213
}
1314

1415
resource "null_resource" "push-lambda-registrator-to-ecr" {

test/acceptance/setup-terraform/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ terraform {
55
required_providers {
66
aws = {
77
source = "hashicorp/aws"
8-
version = "4.14.0"
8+
version = "4.67.0"
99
}
1010
}
1111
}

0 commit comments

Comments
 (0)