Skip to content

Terraform init hooks tutorial #1376

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

Merged
merged 15 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion content/en/references/init-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ In these directories, you can put either executable shell scripts or Python prog
All except `boot.d` will be run in the same Python interpreter as LocalStack, which gives additional ways of configuring/extending LocalStack.
You can also use subdirectories to organize your init scripts.

Currently, known script extensions are `.sh`, and `.py`.
Currently, known script extensions are `.sh` and `.py`.
Additionally, with the installation of the `localstack-extension-terraform-init` [extension]({{<ref "user-guide/extensions/">}}), `.tf` files can also be supported.
Shell scripts have to be executable, and have to have a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) (usually `#!/bin/bash`).

A script can be in one of four states: `UNKNOWN`, `RUNNING`, `SUCCESSFUL`, `ERROR`.
Expand Down Expand Up @@ -154,6 +155,79 @@ DOCKER_FLAGS='-v /path/to/init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh'

Another use for init hooks can be seen when [adding custom TLS certificates to LocalStack]({{< ref "custom-tls-certificates#custom-tls-certificates-with-init-hooks" >}}).

### Terraform configuration files as init hooks

Running Terraform configuration files as init hooks requires the installation of a special extension.
For more information on how to manage [LocalStack extensions]({{< ref "user-guide/extensions/" >}}), please refer to the dedicated documentation page,
and for more details on running init hooks in development mode, you can check out the [extension repository description](https://github.com/localstack/localstack-extensions/tree/main/terraform-init).

##### Usage

Start LocalStack with **`EXTENSION_AUTO_INSTALL="localstack-extension-terraform-init"`**.
Mount a **`main.tf`** file into **`/etc/localstack/init/ready.d`**
When LocalStack starts up, it will install the extension, which in turn installs Terraform and [`tflocal`](https://github.com/localstack/terraform-local) into the container.
If one of the init stage directories contain a `main.tf` file, the extension will run `tflocal init` and `tflocal apply` on that directory.

##### Example

main.tf:

```terraform
resource "aws_s3_bucket" "example" {
bucket = "my-tf-test-bucket"

tags = {
Name = "My bucket"
Environment = "Dev"
}
}
```

Start LocalStack Pro with mounted main.tf:

{{< tabpane >}}
{{< tab header="docker-compose.yml" lang="yml" >}}
version: "3.8"

services:
localstack:
container_name: "localstack-main"
image: localstack/localstack-pro # required for Pro
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
environment:
# Activate LocalStack Pro: https://docs.localstack.cloud/getting-started/auth-token/
- LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?}
- EXTENSION_AUTO_LOAD=localstack-extension-terraform-init
volumes:
# you could also place your main.tf in `./ready.d` and set "./ready.d:/etc/localstack/init/ready.d"
- "./main.tf:/etc/localstack/init/ready.d/main.tf"
- "./volume:/var/lib/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
{{< /tab >}}

{{< tab header="LocalStack CLI" lang="bash" >}}
localstack start \
-e EXTENSION_AUTO_INSTALL="localstack-extension-terraform-init" \
-v ./main.tf:/etc/localstack/init/ready.d/main.tf
{{< /tab >}}
{{< /tabpane >}}

You can wait for LocalStack to complete the startup process, and then print the created S3 bucket:
{{< command >}}
localstack wait && awslocal s3 ls
{{< / command >}}

The logs should show something like:

```bash
2024-06-26T20:36:19.946 INFO --- [ady_monitor)] l.extension : Applying terraform project from file /etc/localstack/init/ready.d/main.tf
2024-06-26T20:36:19.946 DEBUG --- [ady_monitor)] localstack.utils.run : Executing command: ['tflocal', '-chdir=/etc/localstack/init/ready.d', 'init', '-input=false']
2024-06-26T20:36:26.864 DEBUG --- [ady_monitor)] localstack.utils.run : Executing command: ['tflocal', '-chdir=/etc/localstack/init/ready.d', 'apply', '-auto-approve']
```

For a more complex demo project, on how to use Terraform init hooks for your testing environments, you can check out [this example]({{< ref "tutorials/using-terraform-with-testcontainers-and-localstack/" >}}) in the Tutorials section.

## Troubleshooting

If you are having issues with your initialization hooks not being executed, please perform the following checks:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading