Dynamic Packer Variables Name

4.3k views Asked by At

Use-Case is to use PACKER variable file to build AWS AMI in "us-east-1" and "us-east-2" region. I can have two separate file for NV and OH region. But I am trying out if that can be done using same variable file.

Based on the value of variable 'PACKER_BUILD_REGION' in Packer_Var_File.json file, my packer build should select the value specific to NV or OH region only. Any suggestion how to achieve this?

Packer Build Command: packer build -var-file Packer_Var_File.json Packer_Build_File.json

Detail of Packer_Var_File.json file as given below

{
    "PACKER_BUILD_REGION": "NV",

    "1": "This Section to defined 'North Verginia' REGION SPECIFIC Varianles for AMI Build", 
    "!": "================================================================================", 
    "NV_region": "us-east-1",
    "NV_vpc_id": "vpc-00112233",
    "NV_subnet_id": "subnet-001122334455",
    "NV_ssh_keypair_name": "NV_SSH_KEY",
    "NV_ssh_private_key_file": "{{user `NV_ssh_keypair_name`}}.pem", 
    "NV_security_group_ids": "sg-0101010,sg-0202020,sg-03030303",

    "2": "This Section to defined 'OHIO' REGION SPECIFIC Varianles for AMI Build", 
    "@": "======================================================================", 
    "OH_region": "us-east-2",
    "OH_vpc_id": "vpc-33221100",
    "OH_subnet_id": "subnet-554433221100",
    "OH_ssh_keypair_name": "OH_SSH_KEY",
    "OH_ssh_private_key_file": "{{user `OH_ssh_keypair_name`}}.pem", 
    "OH_security_group_ids": "sg-121314,sg-131517",

    "3": "This Section to defined all COMMON Varianles for AMI Build", 
    "#": "==========================================================", 
    "KEY_region":               "{{user `PACKER_BUILD_REGION`}}_region",
    "KEY_vpc_id":               "{{user `PACKER_BUILD_REGION`}}_vpc_id",
    "KEY_subnet_id":            "{{user `PACKER_BUILD_REGION`}}_subnet_id",
    "KEY_source_ami":           "{{user `PACKER_BUILD_REGION`}}_source_ami",
    "KEY_ssh_keypair_name":     "{{user `PACKER_BUILD_REGION`}}_ssh_keypair_name",
    "KEY_ssh_private_key_file": "{{user `PACKER_BUILD_REGION`}}_ssh_private_key_file",
    "KEY_security_group_ids":   "{{user `PACKER_BUILD_REGION`}}_security_group_ids",
    
    "region": "{{ user `KEY_region` }}",
    "vpc_id": "{{user `KEY_vpc_id` }}",
    "subnet_id": "{{user `KEY_subnet_id` }}",
    "ssh_keypair_name": "{{user `KEY_ssh_keypair_name` }}",
    "ssh_private_key_file": ".\\{{user `KEY_ssh_private_key_file`}}",
    "security_group_ids": "{{user `KEY_security_group_ids` }}",
    
    "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
    "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
    "instance_type": "t3.large",
    "iam_profile_name": "Agent_iam_Access",
    "ami_description": "AMI on Windows Server 2019 with JDK 1.8.0_251, Chrome Driver 83.0.3987.106, Chrome Browser 83.0.3987.149, and Selenium 3.7.1 Jar",
    "ami_regions": "us-east-1,us-east-2",
    "ami_users": "01223334444,43322211110"
}

1

There are 1 answers

0
KayD On

You can use the env variables in the packer file. Environment variables can be used within your template using user variables. The env function is available only within the default value of a user variable, allowing you to default a user variable to an environment variable.

I just tested this with a simple packer build one.

var.json

{
    "Data": "{{ env `name`}}"
}

main.json

{
  "builders": [
    {
        "type": "file",
        "content": "{{user `Data`}}",
        "target": "dummy_artifact"
      }
  ]
}

So now I have to set the env variable

  1. name=test1 packer build -var-file var.json main.json
  2. name=test2 packer build -var-file var.json main.json

First run will create a file's content as test1 but second one as test2.


So now let's go back to your example, if you apply same method to your file then, it will not work properly. For example is shown below:

{
    "PACKER_BUILD_REGION": "{{env `MY_CUSTOM_BUILD_REGION `}}"
}

you cannot use variable inside a variable. If you use this then it will not work as you are expecting because the end value will be NV_region instead of us-east-1

so you need to update your variable file.

So you can;'t modify the variables with variables it's better to use two different files for configuration or you can write your own bash script to generate the variables and then modify your variable file to fetch the value from env.