Skip to content

Commit dc4d000

Browse files
feat: Support additional arguments for docker and entrypoint override (#366)
Co-authored-by: Anton Babenko <[email protected]>
1 parent 61180bd commit dc4d000

File tree

7 files changed

+95
-9
lines changed

7 files changed

+95
-9
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,27 @@ Note that by default, the `docker_image` used comes from the registry `public.ec
474474

475475
If you override `docker_image`, be sure to keep the image in sync with your `runtime`. During the plan phase, when using docker, there is no check that the `runtime` is available to build the package. That means that if you use an image that does not have the runtime, the plan will still succeed, but then the apply will fail.
476476

477+
#### Passing additional Docker options
478+
479+
To add flexibility when building in docker, you can pass any number of additional options that you require (see [Docker run reference](https://docs.docker.com/engine/reference/run/) for available options):
480+
481+
```hcl
482+
docker_additional_options = [
483+
"-e", "MY_ENV_VAR='My environment variable value'",
484+
"-v", "/local:/docker-vol",
485+
]
486+
```
487+
488+
#### Overriding Docker Entrypoint
489+
490+
To override the docker entrypoint when building in docker, set `docker_entrypoint`:
491+
492+
```hcl
493+
docker_entrypoint = "/entrypoint/entrypoint.sh"
494+
```
495+
496+
The entrypoint must map to a path within your container, so you need to either build your own image that contains the entrypoint or map it to a file on the host by mounting a volume (see [Passing additional Docker options](#passing-additional-docker-options)).
497+
477498
## <a name="package"></a> Deployment package - Create or use existing
478499

479500
By default, this module creates deployment package and uses it to create or update Lambda Function or Lambda Layer.
@@ -716,7 +737,9 @@ No modules.
716737
| <a name="input_description"></a> [description](#input\_description) | Description of your Lambda Function (or Layer) | `string` | `""` | no |
717738
| <a name="input_destination_on_failure"></a> [destination\_on\_failure](#input\_destination\_on\_failure) | Amazon Resource Name (ARN) of the destination resource for failed asynchronous invocations | `string` | `null` | no |
718739
| <a name="input_destination_on_success"></a> [destination\_on\_success](#input\_destination\_on\_success) | Amazon Resource Name (ARN) of the destination resource for successful asynchronous invocations | `string` | `null` | no |
740+
| <a name="input_docker_additional_options"></a> [docker\_additional\_options](#input\_docker\_additional\_options) | Additional options to pass to the docker run command (e.g. to set environment variables, volumes, etc.) | `list(string)` | `[]` | no |
719741
| <a name="input_docker_build_root"></a> [docker\_build\_root](#input\_docker\_build\_root) | Root dir where to build in Docker | `string` | `""` | no |
742+
| <a name="input_docker_entrypoint"></a> [docker\_entrypoint](#input\_docker\_entrypoint) | Path to the Docker entrypoint to use | `string` | `null` | no |
720743
| <a name="input_docker_file"></a> [docker\_file](#input\_docker\_file) | Path to a Dockerfile when building in Docker | `string` | `""` | no |
721744
| <a name="input_docker_image"></a> [docker\_image](#input\_docker\_image) | Docker image to use for the build | `string` | `""` | no |
722745
| <a name="input_docker_pip_cache"></a> [docker\_pip\_cache](#input\_docker\_pip\_cache) | Whether to mount a shared pip cache folder into docker environment or not | `any` | `null` | no |

examples/build-package/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Note that this example may create resources which cost money. Run `terraform des
5050
| <a name="module_package_with_npm_requirements_in_docker"></a> [package\_with\_npm\_requirements\_in\_docker](#module\_package\_with\_npm\_requirements\_in\_docker) | ../../ | n/a |
5151
| <a name="module_package_with_patterns"></a> [package\_with\_patterns](#module\_package\_with\_patterns) | ../../ | n/a |
5252
| <a name="module_package_with_pip_requirements_in_docker"></a> [package\_with\_pip\_requirements\_in\_docker](#module\_package\_with\_pip\_requirements\_in\_docker) | ../../ | n/a |
53+
| <a name="module_package_with_pip_requirements_in_docker_overriding_entrypoint"></a> [package\_with\_pip\_requirements\_in\_docker\_overriding\_entrypoint](#module\_package\_with\_pip\_requirements\_in\_docker\_overriding\_entrypoint) | ../../ | n/a |
5354

5455
## Resources
5556

examples/build-package/main.tf

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,35 @@ module "package_with_pip_requirements_in_docker" {
131131
build_in_docker = true
132132
}
133133

134+
# Create zip-archive which contains:
135+
# 1. A single file - index.py
136+
# 2. Content of directory "dir2"
137+
# 3. Install pip requirements
138+
# "pip install" is running in a Docker container for the specified runtime
139+
# The docker entrypoint is overridden, allowing you to run additional commands within the container
140+
module "package_with_pip_requirements_in_docker_overriding_entrypoint" {
141+
source = "../../"
142+
143+
create_function = false
144+
145+
runtime = "python3.8"
146+
source_path = [
147+
"${path.module}/../fixtures/python3.8-app1/index.py",
148+
"${path.module}/../fixtures/python3.8-app1/dir1/dir2",
149+
{
150+
pip_requirements = "${path.module}/../fixtures/python3.8-app1/requirements.txt"
151+
}
152+
]
153+
hash_extra = "package_with_pip_requirements_in_docker_overriding_entrypoint"
154+
155+
build_in_docker = true
156+
docker_additional_options = [
157+
"-e", "MY_ENV_VAR='My environment variable value'",
158+
"-v", "${abspath(path.module)}/../fixtures/python3.8-app1/docker/entrypoint.sh:/entrypoint/entrypoint.sh:ro",
159+
]
160+
docker_entrypoint = "/entrypoint/entrypoint.sh"
161+
}
162+
134163
# Create zip-archive which contains content of directory with commands and patterns applied.
135164
#
136165
# Notes:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
set -e
3+
4+
echo in entrypoint
5+
echo I can read $MY_ENV_VAR and my volume:
6+
ls -la /entrypoint
7+
8+
echo "running command $@"
9+
"$@"
10+
11+
echo finished running entrypoint

package.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ def install_pip_requirements(query, requirements_file, tmp_dir):
10051005
'.', shell_command, runtime,
10061006
image=docker_image_tag_id,
10071007
shell=True, ssh_agent=with_ssh_agent,
1008-
pip_cache_dir=pip_cache_dir,
1008+
pip_cache_dir=pip_cache_dir, docker=docker,
10091009
))
10101010
else:
10111011
cmd_log.info(shlex_join(pip_command))
@@ -1260,7 +1260,8 @@ def install_npm_requirements(query, requirements_file, tmp_dir):
12601260
check_call(docker_run_command(
12611261
'.', shell_command, runtime,
12621262
image=docker_image_tag_id,
1263-
shell=True, ssh_agent=with_ssh_agent
1263+
shell=True, ssh_agent=with_ssh_agent,
1264+
docker=docker,
12641265
))
12651266
else:
12661267
cmd_log.info(shlex_join(npm_command))
@@ -1310,7 +1311,8 @@ def docker_build_command(tag=None, docker_file=None, build_root=False):
13101311

13111312
def docker_run_command(build_root, command, runtime,
13121313
image=None, shell=None, ssh_agent=False,
1313-
interactive=False, pip_cache_dir=None, poetry_cache_dir=None):
1314+
interactive=False, pip_cache_dir=None, poetry_cache_dir=None,
1315+
docker=None):
13141316
""""""
13151317
if platform.system() not in ('Linux', 'Darwin'):
13161318
raise RuntimeError("Unsupported platform for docker building")
@@ -1331,6 +1333,9 @@ def docker_run_command(build_root, command, runtime,
13311333
'-v', '{}/.ssh/known_hosts:/root/.ssh/known_hosts:z'.format(home),
13321334
])
13331335

1336+
if docker and docker.docker_additional_options:
1337+
docker_cmd.extend(docker.docker_additional_options)
1338+
13341339
if ssh_agent:
13351340
if platform.system() == 'Darwin':
13361341
# https://docs.docker.com/docker-for-mac/osxfs/#ssh-agent-forwarding
@@ -1362,7 +1367,10 @@ def docker_run_command(build_root, command, runtime,
13621367
if not image:
13631368
image = 'public.ecr.aws/sam/build-{}'.format(runtime)
13641369

1365-
docker_cmd.extend(['--entrypoint', ''])
1370+
if docker and docker.docker_entrypoint:
1371+
docker_cmd.extend(['--entrypoint', docker.docker_entrypoint])
1372+
else:
1373+
docker_cmd.extend(['--entrypoint', ''])
13661374

13671375
docker_cmd.append(image)
13681376

package.tf

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ data "external" "archive_prepare" {
1717
})
1818

1919
docker = var.build_in_docker ? jsonencode({
20-
docker_pip_cache = var.docker_pip_cache
21-
docker_build_root = var.docker_build_root
22-
docker_file = var.docker_file
23-
docker_image = var.docker_image
24-
with_ssh_agent = var.docker_with_ssh_agent
20+
docker_pip_cache = var.docker_pip_cache
21+
docker_build_root = var.docker_build_root
22+
docker_file = var.docker_file
23+
docker_image = var.docker_image
24+
with_ssh_agent = var.docker_with_ssh_agent
25+
docker_additional_options = var.docker_additional_options
26+
docker_entrypoint = var.docker_entrypoint
2527
}) : null
2628

2729
artifacts_dir = var.artifacts_dir

variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,18 @@ variable "docker_pip_cache" {
683683
default = null
684684
}
685685

686+
variable "docker_additional_options" {
687+
description = "Additional options to pass to the docker run command (e.g. to set environment variables, volumes, etc.)"
688+
type = list(string)
689+
default = []
690+
}
691+
692+
variable "docker_entrypoint" {
693+
description = "Path to the Docker entrypoint to use"
694+
type = string
695+
default = null
696+
}
697+
686698
variable "recreate_missing_package" {
687699
description = "Whether to recreate missing Lambda package if it is missing locally or not"
688700
type = bool

0 commit comments

Comments
 (0)