terraform local-exec ausführen - terraform

I would like to perform the following scenario in Terraform:
resource "aws_ecr_repository" "jenkins" {
name = var.image_name
provisioner "local-exec" {
command = "./deploy-image.sh ${self.repository_url} ${var.image_name}"
}
}
However, it is not executed. Does anyone have an idea what could be?

I had to add a working directory
resource "null_resource" "backend_image" {
triggers = {
build_trigger = var.build_trigger
}
provisioner "local-exec" {
command = "./deploy-image.sh ${var.region} ${var.image_name} ${var.ecr_repository}"
interpreter = ["bash", "-c"]
working_dir = "${path.cwd}/${path.module}"
}
}
Now it works.

Related

Terraform local-exec command with complex variables

I'd need to iterate through a list of variables in local-exec provider. Is that possible?
variables.tf:
variable "items" {
default = []
}
main.tf:
resource "null_resource" "loop_list" {
provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = <<EOF
for i in ${join(' ', var.items)}
print $i
done
EOF
}
}
You should be able to use environment. Something like this:
variable "items" {
default = ["item1", "item2"]
}
resource "null_resource" "loop_list" {
provisioner "local-exec" {
command = "for item in $ITEMS; do echo $item >> test-file; done"
environment = { ITEMS = join(" ", var.items) }
}
}
Where terraform apply and cat test-file yields:
item1
item2

How to iterate resources in terraform?

How to iterate resources for different values of a parameter
For example, in my below terraform file I have one data block and one resource. If I pass value DB_NAME=test then its working fine. But what if I have multiple values of DB_NAME and I want it to run multiple time DB_NAME=test, app. How will I iterate over data and resource block? :
data "template_file" "search-index" {
template = "${file("search-index/search-index.sh")}"
vars {
DB_NAME = "${var.DB_NAME}"
}
}
resource "null_resource" "script" {
triggers = {
DB_NAME = "${var.DB_NAME}"
script_sha = "${sha256(file("search-index/search-index.sh"))}"
}
provisioner "local-exec" {
command = "${data.template_file.search-index.rendered}"
interpreter = ["/bin/bash", "-c"]
}
}
I'm not sure if I fully understood what you are trying to achieve but you can create multiple DB by defining a variables.tf like this:
variable "DB_NAME" {
description = "A list of databases"
type = list(string)
default = ["db1", "db2", "db3"]
}
And then using the for_each functionality in your terraform file:
data "template_file" "search-index" {
for_each = toset(var.DB_NAME)
template = "${file("search-index/search-index.sh")}"
vars = {
DB_NAME = each.value
}
}
resource "null_resource" "script" {
for_each = toset(var.DB_NAME)
triggers = {
DB_NAME = each.value
script_sha = "${sha256(file("search-index/search-index.sh"))}"
}
provisioner "local-exec" {
command = "${data.template_file.search-index[each.value]}"
interpreter = ["/bin/bash", "-c"]
}
}

Can terraforms null_resource use timeouts blocks?

I have a terraform null_resource that looks like the following
resource "null_resource" "foo" {
provisioner "local-exec" {
command = "foo.sh"
}
}
So what I would like to know is I can use timeouts with the resource as in the following
resource "null_resource" "foo" {
provisioner "local-exec" {
command = "foo.sh"
}
timeouts {
create = "60m"
delete = "2h"
}
}
I believe the null provider doesn't support timeout operations for it's resources.
However, there should be a way to model this using destroy-time provisioners.
resource "null_resource" "foo" {
provisioner "local-exec" {
command = "timeout 60m foo.sh"
}
provisioner "local-exec" {
command = "timeout 2h foo.sh"
when = "destroy"
}
}

dealing with external data sources when running destroy in terraform

For an external data source, I need to run a bash command when I run terraform destroy.
Is there a way to do an if to trigger this?
data "external" "token" {
program = ["sh", "${path.module}/get_token.sh"]
query = {
controller = "${packet_device.controller.network.0.address}"
}
}
maybe using an if counter? but somehow making sure its run with destroy
count = var.myInitExData ? 1 : 0
Not sure if that works, but you could try null_resource with a Destroy-Time provisioner:
resource "null_resource" "token" {
triggers = {
token = data.external.token.result
}
provisioner "local-exec" {
when = "destroy"
working_dir = path.module
command = "destroy_time_script.sh"
interpreter = ["sh"]
}
}

Run Destroy-Time Provisioner before local_file is deleted

I have a Terraform script which creates a config.json file and then runs a command that uses that config.json:
resource "local_file" "config" {
# Output vars to config
filename = "config.json"
content = "..."
# Deploy using config
provisioner "local-exec" {
command = "deploy"
}
}
This all works great, but when I run terraform destroy I'd like to run a different command - I tried to do this with a destroy-time provisioner in a null_resource by adding the following:
resource "null_resource" "test" {
provisioner "local-exec" {
when = "destroy"
command = "delete"
}
}
The script is run, but it runs after the config file is deleted - it errors, because it needs that config file to exist for it to know what to delete.
How would I fix this?
Thanks!
I moved the destroy time provisioner into the original resource, and it worked great:
resource "local_file" "config" {
# Output vars to config
filename = "config.json"
content = "..."
# Deploy using config
provisioner "local-exec" {
command = "deploy"
}
# Delete on_destroy
provisioner "local-exec" {
when = "destroy"
command = "delete"
}
}

Resources