loading...
Cover image for πŸ‘· How to make conditionnal resources in terraform?

Terraform Conditional Resource πŸ‘· How to make conditionnal resources in terraform?

tbetous profile image Thomas Betous ・2 min read

I’d like to share my experience about conditional resources in terraform with this short article.

Use case πŸ€”

Here is my use case. I am currently experiment lambdas (AWS cloud functions) for a project. My problem is that I don’t know which programming language is the most suitable for my use case. This is why I would like to make a benchmark about execution time and memory consumption for each language.

What I want is to create a terraform configuration that is able to switch my lambda from javascript to java by setting a parameter to "javascript" or "java".

Solution 🀯

My solution was using meta-arguments. The count meta-argument allows to specify how many instances you want to create.

πŸ‘‰ Step 1 : Create your input parameter

variable "lambda_type" {
  type    = "string"
  default = "java"
}

πŸ‘‰ Step 2 : Create your resources

locals {
  my_function_name = "awesome-function"
}

resource "aws_lambda_function" "my_lambda_java" {
  filename         = "lambda.jar"
  function_name    = "${local.my_function_name}"
  handler          = "Handler"
  runtime          = "java8"
  count            = "${var.lambda_type == "java" ? 1 : 0}"
}

resource "aws_lambda_function" "my_lambda_javascript" {
  filename         = "lambda.jar"
  function_name    = "${local.my_function_name}"
  handler          = "index.handler"
  runtime          = "nodejs10.x"
  count            = "${var.lambda_type == "javascript" ? 1 : 0}"
}

Note the ternary condition to set count to 0 or 1 in function of lambda_type value.

πŸ‘‰ Step 3 : Create a data variable to access your conditional resources from the same id

data "aws_lambda_function" "my_lambda" {
  function_name = "${local.my_function_name}"
  depends_on    = ["aws_lambda_function.my_lambda_java", "aws_lambda_function.my_lambda_javascript"]
}

// For instance if your lambda is attached to another resource, 
// you just have to use the same resource id for both (java & javascript)
resource "aws_lambda_permission" "my_lambda_permission" {
  statement_id  = "AllowExecutionFromSNS"
  action        = "lambda:InvokeFunction"
  function_name = "${data.aws_lambda_function.my_lambda.arn}"
  principal     = "sns.amazonaws.com"
  source_arn    = "${aws_sns_topic.topic.arn}"
}

Please note that the depends_on property is really important. If you don't use that property, terraform will try to fetch lambda function that doesn't exist yet. Plus, this only work for terraform 0.12 which allows to use depends_on with resource with count = 0.

πŸ‘‰ Step 4 : Plan and apply your terraform

Finally, you just have to apply your terraform configuration with the suitable parameter :

# For javascript
$ terraform plan --var "lambda-type=javascript"
# If the plan is correct to what you expect :
$ terraform apply --var "lambda-type=javascript"

# For java
$ terraform plan --var "lambda-type=java"
# If the plan is correct to what you expect :
$ terraform apply --var "lambda-type=java"

πŸ‘‰ Step 5 : Clean resources (optional)

If you did some tests by following this article, do not forget to clean your environment by destroying resources !

$ terraform destroy

Congratulations ! πŸŽ‰

Congratulations ! You did it ! Now you can add resources conditionnaly and therefore make your terraform configuration more parameterizable !

If you liked this post, do not hesitate to :

  • Follow me on twitter: @tbetous
  • Share this post !

Thank You for showing interest and reading this πŸŽ‰

Posted on by:

tbetous profile

Thomas Betous

@tbetous

Software Engineer @ZenikaIT β€’ Passionate about Web & Cloud

Discussion

markdown guide
 

You can do something like:

resource "aws_lambda_function" "my_lambda" {
  filename = "lambda.jar"
  function_name = "${local.my_function_name}"
  handler = "${var.lambda_type == "java" ? "Handler" : "index.handler"}"
  runtime = "${var.lambda_type == "java" ? "java8" : "nodejs10.x"}"
}

and no need to create 2 resources, and data to refer the one that got created.

 

I havn't tested your suggestion but it seems to be a great solution ! I'll definitvly test that next time !

Thanks for your comment.

 

What if I want to create a resource on multiple conditions (I cannot use count twice, and I cannot use terraform 0.12+) ?