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

Ajsanon/ux updates #80

Merged
merged 14 commits into from
Sep 1, 2023
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ FEATURES
* 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.
[[GH-78]](https://github.com/hashicorp/terraform-aws-consul-lambda/pull/78)

* Add support for pushing `consul-lambda-registrator` public image to private ecr repo through terraform.
[[GH-80]](https://github.com/hashicorp/terraform-aws-consul-lambda/pull/80)

## 0.1.0-beta4 (Apr 28, 2023)

IMPROVEMENTS
Expand Down
51 changes: 4 additions & 47 deletions examples/lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,57 +51,16 @@ cd terraform-aws-consul-lambda/examples/lambda
git checkout v${VERSION}
```

## Set your AWS account ID and region
## Set your AWS region

Subsequent steps require knowledge of your AWS account ID and the AWS region that you want to deploy the example resources to.
Subsequent steps require knowledge of the AWS region that you want to deploy the example resources to.
Export these values to environment variables using the commands below.
Replace `<account_id>` and `<region>` with your AWS account ID and region, respectively.
Replace `<region>` with your AWS region.

```shell
export AWS_ACCOUNT_ID=<account_id>
export AWS_REGION=<region>
```

## Publish `consul-lambda-registrator`

In this section you will pull the `consul-lambda-registrator` image from the AWS Public ECR Gallery and publish it to a private ECR repository using `docker`. This is required because AWS Lambda functions must use images from a private ECR repository. They are not able to use images from the Public ECR Gallery.

### Pull `consul-lambda-registrator`

Use the following command to pull the `consul-lambda-registrator` from the AWS Public ECR to your local machine.

```shell
docker pull public.ecr.aws/hashicorp/consul-lambda-registrator:${VERSION}
```

### Log in to AWS ECR

```shell
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
```

### Create a private ECR repository

Use the following command to create a private ECR repository for `consul-lambda-registrator`.

```shell
aws ecr create-repository \
--repository-name consul-lambda-registrator \
--image-scanning-configuration scanOnPush=true \
--region ${AWS_REGION}
```

### Push `consul-lambda-registrator`

Use the following commands to push the `consul-lambda-registrator` image to the private ECR repository you created in the previous step.

```shell
docker tag \
public.ecr.aws/hashicorp/consul-lambda-registrator:${VERSION} \
${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/consul-lambda-registrator:${VERSION}

docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/consul-lambda-registrator:${VERSION}
```
aahel marked this conversation as resolved.
Show resolved Hide resolved

## Download the `consul-lambda-extension`

Expand All @@ -110,7 +69,7 @@ This example Terraform workspace will use the zip package to deploy the `consul-
add it to the `lambda-app-2` function so that it can call services within the Consul service mesh.

```shell
curl -o consul-lambda-extension.zip https://releases.hashicorp.com/consul-lambda-extension/${VERSION}/consul-lambda-extension_${VERSION}_linux_amd64.zip
curl -o consul-lambda-extension.zip "https://releases.hashicorp.com/consul-lambda-extension/${VERSION}/consul-lambda-extension_${VERSION}-beta4_linux_amd64.zip"
```

## Build the example Lambda function
Expand Down Expand Up @@ -139,7 +98,6 @@ terraform init
terraform apply \
-var "name=${USER}" \
-var "region=${AWS_REGION}" \
-var "ecr_image_uri=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/consul-lambda-registrator:${VERSION}" \
-var "ingress_cidrs=[\"${MY_IP}\"]"
```

Expand Down Expand Up @@ -261,7 +219,6 @@ Use the following command to clean up the resources managed by Terraform.
terraform destroy \
-var "name=${USER}" \
-var "region=${AWS_REGION}" \
-var "ecr_image_uri=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/consul-lambda-registrator:${VERSION}" \
-var "ingress_cidrs=[\"${MY_IP}\"]"
```

Expand Down
2 changes: 1 addition & 1 deletion examples/lambda/lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ variable "invocation_mode" {
default = "SYNCHRONOUS"
validation {
condition = contains(["SYNCHRONOUS", "ASYNCHRONOUS"], var.invocation_mode)
error_message = "invocation_mode must be one of SYNCHRONOUS or ASYNCHRONOUS"
error_message = "Variable invocation_mode must be one of SYNCHRONOUS or ASYNCHRONOUS."
}
}

Expand Down
3 changes: 2 additions & 1 deletion examples/lambda/registrator.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
module "consul_lambda_registrator" {
source = "../../modules/lambda-registrator"
name = "${var.name}-lambda-registrator"
ecr_image_uri = var.ecr_image_uri
consul_http_addr = "http://${module.dev_consul_server.server_dns}:8500"
consul_extension_data_prefix = "/${var.name}"
subnet_ids = module.vpc.private_subnets
security_group_ids = [module.vpc.default_security_group_id]
sync_frequency_in_minutes = 1
enable_pull_through_cache = var.enable_pull_through_cache
region = var.region
}
11 changes: 9 additions & 2 deletions examples/lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ variable "name" {
type = string
}

variable "ecr_image_uri" {
description = "The private ECR image URI for consul-lambda-registrator."
variable "lambda_registrator_image" {
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like a breaking change to me. We should probably mark it as a breaking change in the changelog.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm also assuming this breaks the acceptance tests

ecr_image_uri = var.ecr_image_uri

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree. I missed this in my review. We need to open a PR to update the CHANGELOG for this.

description = "The Consul Lambda Registrator image for consul-lambda-registrator."
type = string
default = "public.ecr.aws/hashicorp/consul-lambda-registrator:0.1.0-beta4"
}

variable "region" {
Expand Down Expand Up @@ -38,3 +39,9 @@ variable "consul_lambda_extension_arn" {
type = string
default = ""
}

variable "enable_pull_through_cache" {
description = "Flag to determine if a pull-through cache method will be used to obtain the appropriate ECR image"
type = bool
default = false
}
83 changes: 80 additions & 3 deletions modules/lambda-registrator/main.tf
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
}
}
locals {
on_vpc = length(var.subnet_ids) > 0 && length(var.security_group_ids) > 0
vpc_config = local.on_vpc ? [{
subnet_ids = var.subnet_ids
security_group_ids = var.security_group_ids
}] : []
cron_key = "${var.name}-cron"
lambda_events_key = "${var.name}-lambda_events"
cron_key = "${var.name}-cron"
lambda_events_key = "${var.name}-lambda_events"
image_parts = split(":", var.consul_lambda_registrator_image)
image_tag = local.image_parts[1]
image_path_parts = split("/", local.image_parts[0])
image_username = local.image_path_parts[1]
image_name = local.image_path_parts[2]
ecr_image_uri = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com/${var.private_ecr_repo_name}:${local.image_tag}"
ecr_image_uri_pull_through = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com/${var.ecr_repository_prefix}/${local.image_username}/${local.image_name}:${local.image_tag}"
}

# Equivalent of aws ecr get-login
data "aws_ecr_authorization_token" "ecr_auth" {}

provider "docker" {
host = var.docker_host
registry_auth {
username = data.aws_ecr_authorization_token.ecr_auth.user_name
password = data.aws_ecr_authorization_token.ecr_auth.password
address = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com"
}
}

data "aws_caller_identity" "current" {}

resource "aws_iam_role" "registration" {
name = var.name

Expand Down Expand Up @@ -127,8 +156,51 @@ resource "aws_iam_role_policy_attachment" "lambda_logs" {
policy_arn = aws_iam_policy.policy.arn
}

resource "aws_ecr_repository" "lambda-registrator" {
count = var.enable_pull_through_cache ? 0 : 1
name = var.private_ecr_repo_name
force_delete = true
}


resource "aws_ecr_pull_through_cache_rule" "pull_through_cache_rule" {
count = var.enable_pull_through_cache ? 1 : 0
ecr_repository_prefix = var.ecr_repository_prefix
upstream_registry_url = var.upstream_registry_url
}

resource "docker_image" "lambda_registrator" {
name = var.enable_pull_through_cache ? local.ecr_image_uri_pull_through : var.consul_lambda_registrator_image
depends_on = [
aws_ecr_pull_through_cache_rule.pull_through_cache_rule
]
}

resource "docker_tag" "lambda_registrator_tag" {
count = var.enable_pull_through_cache ? 0 : 1
source_image = docker_image.lambda_registrator.name
target_image = local.ecr_image_uri
}

resource "null_resource" "push_image" {
Copy link
Contributor

Choose a reason for hiding this comment

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

We originally didn't include this because it breaks TFC. It looks like this PR only allows using a pull through cache or pushing docker images. This effectively requires TFC users to use the pull through cache approach.

Is this a tradeoff we are ok with?

count = var.enable_pull_through_cache ? 0 : 1

provisioner "local-exec" {
command = "docker push ${local.ecr_image_uri}"
}

depends_on = [
docker_tag.lambda_registrator_tag
]
}
resource "time_sleep" "wait_30_seconds" {
aahel marked this conversation as resolved.
Show resolved Hide resolved
count = var.enable_pull_through_cache ? 1 : 0
depends_on = [docker_image.lambda_registrator]

create_duration = "30s"
}
resource "aws_lambda_function" "registration" {
image_uri = var.ecr_image_uri
image_uri = var.enable_pull_through_cache ? local.ecr_image_uri_pull_through : local.ecr_image_uri
package_type = "Image"
function_name = var.name
role = aws_iam_role.registration.arn
Expand Down Expand Up @@ -168,6 +240,11 @@ resource "aws_lambda_function" "registration" {
security_group_ids = vpc_config.value["security_group_ids"]
}
}
depends_on = [
null_resource.push_image,
time_sleep.wait_30_seconds,
]

}

module "eventbridge" {
Expand Down
56 changes: 46 additions & 10 deletions modules/lambda-registrator/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ variable "reserved_concurrent_executions" {
default = -1
}

variable "ecr_image_uri" {
description = <<-EOT
The ECR image URI for consul-lambda-registrator. The image must be in the
same AWS region and in a private ECR repository. Due to these constraints,
the public ECR images (https://gallery.ecr.aws/hashicorp/consul-lambda-registrator)
cannot be used directly. We recommend either creating and using a new ECR
repository or configuring pull through cache rules (https://docs.aws.amazon.com/AmazonECR/latest/userguide/pull-through-cache.html).
EOT
type = string
}

variable "sync_frequency_in_minutes" {
description = "The interval EventBridge is configured to trigger full synchronizations."
Expand All @@ -109,3 +99,49 @@ variable "tags" {
type = map(string)
default = {}
}
variable "region" {
type = string
description = "AWS region to deploy Lambda registrator."
}

variable "private_ecr_repo_name" {
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. Note :- If 'enable_pull_through_cache' is true this variable is ignored."
type = string
default = "consul-lambda-registrator"
}

variable "enable_pull_through_cache" {
description = "Flag to determine if a pull-through cache method will be used to obtain the appropriate ECR image"
type = bool
default = false
}
aahel marked this conversation as resolved.
Show resolved Hide resolved


variable "consul_lambda_registrator_image" {
description = "The Lambda registrator image to use. Must be provided as <registry/repository:tag>"
type = string
default = "public.ecr.aws/hashicorp/consul-lambda-registrator:0.1.0-beta4"

validation {
condition = can(regex("^[a-zA-Z0-9_.-]+/[a-z0-9_.-]+/[a-z0-9_.-]+:[a-zA-Z0-9_.-]+$", var.consul_lambda_registrator_image))
error_message = "Image format of 'consul_lambda_registrator_image' is invalid. It should be in the format 'registry/repository:tag'."
}
}

variable "docker_host" {
description = "The docker socket for your system"
type = string
default = "unix:///var/run/docker.sock"
}

variable "ecr_repository_prefix" {
description = "The repository namespace to use when caching images from the source registry"
type = string
default = "ecr-public"
}

variable "upstream_registry_url" {
description = "The public registry url"
type = string
default = "public.ecr.aws"
}
Loading