1

I'm using terraform. I need to create ec2 instance with user data (that install several packages any other things). From this ec2 I need to create ami with same user data. Does terraform "wait" before create ami, so the ami has user data?

I've done a test where user data install docker, and every things works fine, but, what happen if the user data script is too heavy or the connection is too slow?

Here my code

resource "aws_instance" "golden_docker" {
  ami = "ami-ID"
  disable_api_termination = false
  ebs_optimized = true
  instance_type = "t3.medium"
  root_block_device {
    volume_size = 8
  }
  user_data = <<EOF
${file("${path.module}/init_golden.sh")}
EOF
}



resource "aws_ami_from_instance" "golden_ami" {
  name               = "ami-docker"
  source_instance_id = aws_instance.golden_docker.id

}

EDIT: With a user_data like this:

cd /
sudo touch daniele
sudo chown ubuntu:ubuntu daniele
sudo echo $(date) > daniele
sudo echo "start" >> daniele
sleep 30
sudo touch "daniele-1"
sudo echo $(date) >> daniele
sleep 30
sudo touch "daniele-2"
sudo echo $(date) >> daniele
sleep 30
sudo touch "daniele-3"
sudo echo $(date) >> daniele
sleep 60
sudo touch "daniele-4"
sudo echo $(date) >> daniele

sudo touch "daniele-finito"

the script stop to execute when ami starts to build. So when ec2 status check is "passed". If my user_data is too heavy, the ami will not contains all commands, and the execution of user_data will stop.

Thank you

1
  • In your case the "aws_ami_from_instance" has implicit dependency on "aws_instance" (bcoz it depends on the id). So yes terraform will not start creating the second resource until first is completed Commented Jan 21, 2022 at 13:34

2 Answers 2

3

There are two types of dependencies between resources in Terraform:

  1. explicit - using depends_on [1]
  2. implicit - using attributes available after the resource is created [2]

In this case, the second resource, aws_ami_from_instance, has an implicit dependency on the first resource, i.e., aws_instance. You can see this here:

source_instance_id = aws_instance.golden_docker.id

As far as Terraform is concerned, it will not start creating anything new until the first resource in order is done, then second etc. However, you can set a timeouts block for the aws_ami_from_instance [3] in order to tell Terraform to stop waiting after that period. It is 40 minutes by default. More information about timeouts block can be found here [4].

EDIT: If the connection breaks during apply step, Terraform will mark the resource as tainted in the state file [5]. This means that when you run terraform apply it will recreate the resource.


[1] https://www.terraform.io/language/meta-arguments/depends_on

[2] https://www.terraform.io/language/resources/behavior#resource-dependencies

[3] https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ami_from_instance#timeouts

[4] https://www.terraform.io/language/resources/syntax#operation-timeouts

[5] https://www.terraform.io/cli/state/taint#the-tainted-status

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I've tried with a sleep command and touch command. The purpose is to see if the script finish the execution. everything works fine for sleep 120, but not with sleep 900 (this is an example).
I'd expect the second one to be an issue with the default SSH timeout which is not related to Terraform but to the SSH daemon settings.
1

aws_ami_from_instance wait the complete start up of related EC2, but not wait the complete execution of user_data. So I deploy the creation of EC2 (aws_instance), before, and then the creation of AMI (aws_ami_from_instance). Now I'm sure the AMI has execute all user_data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.