Quantcast
Channel: Terraform - HashiCorp Discuss
Viewing all 11357 articles
Browse latest View live

Terraform for_each if value exists in object

$
0
0

I would like to dynamically create some subnets and route tables from a .tfvars file, and then link each subnet to the associated route table if specified.

Here is my .tfvars file:

vnet_spoke_object                      = {
    specialsubnets                     = {
        Subnet_1                       = {
            name                       = "test1"
            cidr                       = ["10.0.0.0/28"]
            route                      = "route1"
        }
        Subnet_2                       = {
            name                       = "test2"
            cidr                       = ["10.0.0.16/28"]
            route                      = "route2"
        }
        Subnet_3                       = {
            name                       = "test3"
            cidr                       = ["10.0.0.32/28"]
        }
    }
}

route_table                            = {
    route1                             = {
        name                           = "route1"
        disable_bgp_route_propagation  = true
        route_entries                  = {
            re1                        = {
                name                   = "rt-rfc-10-28"
                prefix                 = "10.0.0.0/28"
                next_hop_type          = "VirtualAppliance"
                next_hop_in_ip_address = "10.0.0.10"
            }
        }
    }
    route2                             = {
        name                           = "route2"
        disable_bgp_route_propagation  = true
        route_entries                  = {
            re1                        = {
                name                   = "rt-rfc-10-28"
                prefix                 = "10.0.0.16/28"
                next_hop_type          = "VirtualAppliance"
                next_hop_in_ip_address = "10.0.0.10"
            }
        }
    }
}

…and here is my build script:

provider "azurerm" {
    version                        = "2.18.0"
    features{}
}

variable "ARM_LOCATION" {
    default                        = "uksouth"
}

variable "ARM_SUBSCRIPTION_ID" {
    default                        = "asdf-b31e023c78b8"
}

variable "vnet_spoke_object" {}
variable "route_table" {}

module "names" {
    source                         = "./nbs-azure-naming-standard"
    env                            = "dev"
    location                       = var.ARM_LOCATION
    subId                          = var.ARM_SUBSCRIPTION_ID
}

resource "azurerm_resource_group" "test" {
    name                           = "${module.names.standard["resource-group"]}-vnet"
    location                       = var.ARM_LOCATION
}

resource "azurerm_virtual_network" "test" {
    name                           = "${module.names.standard["virtual-network"]}-test"
    location                       = var.ARM_LOCATION
    resource_group_name            = azurerm_resource_group.test.name
    address_space                  = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "test" {
    for_each                       = var.vnet_spoke_object.specialsubnets
    name                           = "${module.names.standard["subnet"]}-${each.value.name}"
    resource_group_name            = azurerm_resource_group.test.name
    virtual_network_name           = azurerm_virtual_network.test.name
    address_prefixes               = each.value.cidr
}

resource "azurerm_route_table" "test" {
    for_each                       = var.route_table
    name                           = "${module.names.standard["route-table"]}-${each.value.name}"
    location                       = var.ARM_LOCATION
    resource_group_name            = azurerm_resource_group.test.name
    disable_bgp_route_propagation  = each.value.disable_bgp_route_propagation
    dynamic "route" {
        for_each                   = each.value.route_entries
        content {
            name                   = route.value.name
            address_prefix         = route.value.prefix
            next_hop_type          = route.value.next_hop_type
            next_hop_in_ip_address = contains(keys(route.value), "next_hop_in_ip_address") ? route.value.next_hop_in_ip_address: null
        }
    }
}

That part works fine in creating the vnet/subnet/route resources, but the problem I face is to dynamically link each subnet to the route table listed in the .tfvars. Not all the subnets will have a route table associated with it, thus it will need to only run IF the key/value route is listed.

resource "azurerm_subnet_route_table_association" "test" {
    for_each                       = {
        for key, value in var.vnet_spoke_object.specialsubnets:
            key => value
            if value.route != null
    }

    lifecycle {
        ignore_changes             = [
            subnet_id
        ]
    }
    subnet_id                      = azurerm_subnet.test[each.key].id
    route_table_id                 = azurerm_route_table.test[each.key].id
}

The error I face with the above code is:

Error: Unsupported attribute

  on main.tf line 65, in resource "azurerm_subnet_route_table_association" "test":
  65:             if value.route != null

This object does not have an attribute named "route".

I have tried various ways with no success, and I’m at a loss here and would appreciate any guidance posisble.

1 post - 1 participant

Read full topic


Generate IAM JSON Policy via Map

$
0
0

Team,
I am trying to create a IAM assume policy in JSON format from a map. I will be grateful if someone can help me here.

locals {
test = {
    cluster1 = {
      ns = "ns1"
      oidc = "oidc1"
    },
    cluster2 = {
      ns = "ns2"
      oidc = "oidc2"
    },
    cluster3 = {
      ns = "ns3"
      oidc = "oidc3"
    }
  }
}

Expected Output

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::12312:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/<oidc1>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "oidc.eks.us-west-2.amazonaws.com/id/<oidc1>:sub": "system:serviceaccount:<ns1>:*"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::12312:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/<oidc2>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "oidc.eks.us-west-2.amazonaws.com/id/<oidc2>:sub": "system:serviceaccount:<ns2>:*"
        }
      }
    },
   {
  "Effect": "Allow",
  "Principal": {
    "Federated": "arn:aws:iam::12312:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/<oidc3>"
  },
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringLike": {
      "oidc.eks.us-west-2.amazonaws.com/id/<oidc3>:sub": "system:serviceaccount:<ns3>:*"
    }
  }
},
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

The above expected policy will then be attached to a IAM role.

@apparentlymart

1 post - 1 participant

Read full topic

Error: Invalid template interpolation value in nrql using list input variable

$
0
0

I am using terraform to create a new relic dashboard , where one of the widget needs to use a list variable of numbers in where clause .
list variable name : vs
variable decalation
vs {
type = list(number)
default = [1,2,3]
}
So my query looks something like this in a widget :
select avg(a) from b where c in (’${var.vs}’)
I want to the list variable values for ‘c’

I am getting the error :
var.vs is list of number with 3 elements
Cannot include the given value in a string template: string required.

1 post - 1 participant

Read full topic

How to give distinct name to instances created as part of autoscaling group in AWS?

$
0
0

Hi,

I want to know whether there is any way to generate unique names to instances created as part of autoscaling group. I am using the community module.

This is a relevant snippet:

module "docker-swarm-manager-asg" {
source = “terraform-aws-modules/autoscaling/aws”
version = “~> 3.0”
name = “ var.environment− {var.role}”
lc_name = “ var.environment− {var.role}-launch-configuration”
image_id = data.aws_ami.docker-swarm-manager-ami.image_id

This creates the instances but provides same name. I want to have some differentiator in the names. It may be good to have names like ‘dev-docker-swarm-manager-1’, ‘dev-docker-swarm-manager-2’ and such, but I would be okay with anything random like ‘dev-docker-swarm-manager-xxxyyy’ and such.

1 post - 1 participant

Read full topic

Adding automatic environment variable to EC2 instance

$
0
0

Is there any way to set environment variables on the EC2 instance automatically via terraform?
the EC2 instance lunching a bash script that includes passphrases, right now they are hardcoded, I would like to use $env_var in the bash script, that this var be automatically set by terraform.
The preferred way:
set env variable in local environment (maybe TF_VAR_*)
terraform takes this var and sets it when EC2 system boots (automation)
bash script is running using the env variable that was set automatically during boot.

1 post - 1 participant

Read full topic

Issues Destroying EC2 Instances in Terraform

$
0
0

I’ve attempted to research the following in google but surprisingly I haven’t found a straight forward answer:

  1. How would I delete specific EC2 instances by passing the instance id as it appears in AWS? For example, when I used terraform to create my instances, AWS automatically created ids for them such as “i-0XXXXXXXXXXXXXXXX”. Is there a command such as "terraform destroy -id=“i-0XXXXXXXXXXXXXXXX”.

  2. How would I delete multiple EC2 instances by passing the name I specified in the main.tf file? For example, I created 2 resource blocks that say “resource ‘aws_instance’ ‘Udacity_foo’”. How can I pass ‘Udacity_foo’ into a command such as “terraform destroy -name=‘Udacity_foo’”, which would delete all instances matching Udacity_foo as terraform recognizes it.

  3. Are tasks 1 and 2 above possible by using a terraform configuration file? For example, I could write “instances_to_delete.tf” and type a command such as "terraform destroy -config=‘instances_to_delete.tf’.

1 post - 1 participant

Read full topic

Terraform Destroy issue with Role Assignment TF resources on locked Azure resources

$
0
0

I am running into this issue running Terraform destroy. I have a storage account that is deployed via different deployment (different TF workspace and different RG in Azure. This Storage account is locked for a good reason. I have another deployment that creates a role assignment for an MSI to this storage account . All this works fine except when doing a destroy it complains that it cannot delete the role assignment because the storage account is locked. Currently i have to remove the lock on the storage account, then run destroy and go and put the lock back. #1887 says it is fixed. Any thoughts are appreciated.

1 post - 1 participant

Read full topic

Upload failed: wait: remote command exited without exit status or exit signal

$
0
0

Hi Team,

I am getting error while trying to upload file from local to remote vm.

Please help in this
Error file attached [error.txt|attachment]
(upload://1hhtcEr1C1zMyhIWDzXMlSLiwbj.txt) (4.4 KB)

1 post - 1 participant

Read full topic


Migration from agent_pool_profile to default_node_pool

$
0
0

Hello,

I am currently upgrading my terraform stack with azurerm from the version 1.x to the version 2.x.

I make all the changes from the terraform files, but when trying to apply the configuration, I am getting the following error:

Error: flattening default_node_pool: The Default Agent Pool “” was not found

After some investigation in a new deployed stack and the old one, I can see that the block agent_pool_profile is existing in the old terraform state file, but has been replaced by default_node_pool in the new terraform state file.

Which is also mentioned here https://www.terraform.io/docs/providers/azurerm/guides/2.0-upgrade-guide.html#removal-of-deprecated-fields-data-sources-and-resources

How can I upgrade my stack using k8s with that kind of changes? (I just hope I should not update the tfstate file manually :sweat_smile:)

Thank you!

1 post - 1 participant

Read full topic

How to get region for provider configuration under v0.13.0-beta3

$
0
0

Can you please tell me how to get the region of the provider?

My configuration:

provider "google" {
  project = "project"
  region  = "europe-west1"
}
...

In:

terraform --version
Terraform v0.12.25
+ provider.google v3.29.0

I have in planfile:

    "provider_config": {
      "google": {
        "name": "google",
        "expressions": {
          "credentials": {},
          "project": {
            "constant_value": "project"
          },
          "region": {
            "constant_value": "europe-west1"
          }
        }
      }
    }

But in:

Terraform v0.13.0-beta3
+ provider registry.terraform.io/hashicorp/google v3.29.0

In planfile we dont have provider_config setting only name:

    "provider_config": {
      "google": {
        "name": "google"
      }
    }

Thanks!

P.S. Sorry if it, not best place to ask such kind of question.)

2 posts - 2 participants

Read full topic

Terraform import doesn't import password for aws_db_instance AWS resource

$
0
0

Hello,

I’m finding that when using terraform import command to import an aws_db_instance AWS resource that it will not import the password, which is the master password into the state file. I’m using S3 for remote state file and using Terraform 0.11.14. Example of the import command used is below.

terraform import module.my_test_rds.aws_db_instance.my_test_rds my_test_rds

This did import successfully into the remote state file other than the missing password. When I run terraform plan against the new state file, the only change shows is the password since the password is not in the new state file.

Is this how terraform import works where it doesn’t import sensitive data, e.g., passwords or am I missing a step?

Thanks,
Mike

1 post - 1 participant

Read full topic

Corporate CLA info?

$
0
0

Hi, my team has a PR for terraform that needs a CLA signed. My employer prefers to sign corporate CLAs to avoid managing agreements covering individual contributors. The individual CLA mentions this possibility in section 4, but there’s no info on what to do.

But how do I get a corporate CLA going?

Thanks,
Ross

1 post - 1 participant

Read full topic

Destruction plan on Terraform Cloud

$
0
0

Hi

Is it possible to create a destruction plan for a workspace in Terraform Cloud?

I have some resources that I marked to prevent destroy, but when I destroy the resources it fails because of that.

I want to destroy only specific components but I can’t find a way to set up the plan.

1 post - 1 participant

Read full topic

How to create a Kubernetes secret with multiple KVPs from a variable collection

$
0
0

I’ve been trying to figure out how to create a Kubernetes secret that will have an id, description and collection of key value pares, all from an input variable.
I’m having two issues.

  1. I can’t figure out how to create a TF .12 variable that has those three properties, one of which is a list object
  2. I can’t figure out how to spit out a list in the data field.
    Here’s some sample code

This is the kind of thing I’m trying to do in creating the variable. This does not work

# Optional additional secrets to be created in Rancher / Kubernetes for injection into a build pod
variable "additional_text_secrets" {
  type = object ({
    id = string
    description = string
    list(object({
      key = string
      value = string
    }))
  })
  default = {[]}
  description = "An additional list of Rancher secrets to create for the user to inject into build pods"
}

This produces the error:
On .terraform\modules\jenkins\variables.tf line 189: Expected an attribute value, introduced by an equals sign ("=").

To create the secret I’m trying something like this.

# Additional Rancher / Kubernetes secrets that the user might need to inject into their build pods
# Text based secrets, we will base64 encode these for the user
resource "rancher2_secret" "additional-text-secrets" {
  name = var.additional_text_secrets.id
  description = var.additional_text_secrets.description
  project_id = var.rancher_project
  namespace_id = rancher2_namespace.jenkins-namespace.id
  labels = {
    "cattle.io/creator" = "norman"
  }
  data = {
    %{ for secret in var.additional_text_secrets.secret }
    secret.key = base64encode("${secret.value}")
    %{ endfor }
  }
}

This produces the error
On .terraform\modules\jenkins\secrets.tf line 11: Expected the start of an expression, but found an invalid expression token.
Note: The above is a Rancher2 secret, i.e. not a straight up k8s secret but I don’t think that matters??
I’m trying the above because I found out that this works

# Create a list of container repository auths used to store Docker images, usually in Artifactory
resource "rancher2_secret" "container-repositories" {
  name = "container-repositories"
  description = "List of container repository auths used to store Docker images, usually in Artifactory"
  project_id = var.rancher_project
  namespace_id = rancher2_namespace.jenkins-namespace.id
  # Using a heredoc becuase you can't pass a complex object to a template
  data = {
    "config.json" = base64encode(<<EOT
{
	"auths": {
		%{ for auth in var.container_repositories }
		"${auth.url}": {
			"username": "${auth.username}",
			"password": "${auth.password}"
		},
		%{ endfor }
	}
}
EOT
      )
  }
}

Which is basically the same thing, except I’m creating a list of auths in JSON format as the value inside of base64encode (so that’s probably why it works, it is inside the function . . . )

Also note that I know I could just create a list of secrets and do this

# A file that has already been base64 encoded
resource "rancher2_secret" "additional-file-secrets" {
  count = length(var.additional_file_secrets)
  name = var.additional_file_secrets[count.index].id
  description = var.additional_file_secrets[count.index].description
  project_id = var.rancher_project
  namespace_id = rancher2_namespace.jenkins-namespace.id
  labels = {
    "cattle.io/creator" = "norman"
  }
  data = {
    var.additional_file_secrets[count.index].file_name = var.additional_file_secrets[count.index].encoded_bytes
  }
}

However that is not as useful as it creates many secrets, one per item in the list and NOT one secret with many key value pares.
This is what we are doing now and found the one major issue is that you cannot mount more than secret to a volume location at a time.

The expected input and output should look like the below
Variable assignment

 additional_text_secrets = {
    id = "sarge-test-secret-1"
    description = "This is a test of a multi value secret"
    secret = [
      {
        key = "secret1"
        value = "This is the value"
      },
      {
        key = "secret2"
        value = "This is the second value."
      }
    ]
  }

Output

resource "rancher2_secret" "additional-text-secrets" {
  name = "sarge-test-secret-1"
  description = "This is a test of a multi value secret"
  project_id = var.rancher_project
  namespace_id = rancher2_namespace.jenkins-namespace.id
  labels = {
    "cattle.io/creator" = "norman"
  }
  data = {
    "secret1" = base64encode("This is the value")
    "secret2" = base64encode("This is the second value")
  }
}

I’m starting to think there isn’t a way to do this, would love it if I’m proved wrong.

3 posts - 2 participants

Read full topic

[Provider SDK] Dealing with conflicts between attributes in different resources

$
0
0

Hello,
What is the best way to deal with conflicts between attributes in different resources? Within a resource there is the ConflictsWith field that can provide a plan time check for conflicting attributes being set. What about with attributes in different resources? Currently, we can pass this check off to the backend API and assume we will get an error if the user sets an invalid configuration. However, I was wondering if there is anything I can do on the Terraform side (preferably at plan time) to check for these sorts of conflicts?

3 posts - 2 participants

Read full topic


Terraform template for input_parameter for aws_config_config_rule

$
0
0

I am trying to apply https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-policy-not-more-permissive.html into a terraform template.
Now, in the input_parameters I need to pass the control policy statement.
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Principal”: {
“AWS”: “11112222333”
},
“Effect”: “Allow”,
“Action”: “s3:GetObject”,
“Resource”: “"
},
{
“Principal”: {
“AWS”: “44445556666”
},
“Effect”: “Allow”,
“Action”: "s3:
”,
“Resource”: “*”
}
]
}

However, Terraform apply keeps throwing me an error :slight_smile:Failed to create AWSConfig rule: InvalidParameterValueException: Blank spaces are not acceptable for input parameter statement.

Can somebody please advise.

1 post - 1 participant

Read full topic

Can't deploy a zip file to a function_app_slot on windows/Azure

$
0
0

My team is having trouble getting a zip file to publish to a functionapp slot on a windows server. Does anyone have any example configuration for making this work? I have only found bits and pieces of a solution.

Not sure if WEBSITE_RUN_FROM_PACKAGE should be set to 1 (for windows) or the url to the blob as in other examples…

1 post - 1 participant

Read full topic

Mlock, golang, docker, random and Ubuntu 20.04

$
0
0

Hi,

I wasn’t sure if this counted as a bug or not so I’m raising here rather than in Github.

I recently saw odd error messages when attempting terraform plan in a docker container on Ubuntu 20.04. Specifically from the random provider.

failed to retrieve schema from provider “random”: rpc error: code = Unavailable desc = connection error: desc = “transport: authentication handshake failed: EOF

I’ve written up more details here https://blog.gripdev.xyz/2020/07/14/terraform-docker-ubuntu-20-04-go-1-14-and-memlock-down-the-rabbit-hole/

It looks like this relates to a workaround used in go 1.14 and it’s affect on the Ubuntu kernel

I’m not sure if there is a change that can be made, for example to the version of go used, which would mean this didn’t affect users.

One thing that did happen was I lost a lot of time thinking this was an issue with the GRPC link rather than the provider crashing. It would be great to get the crash highlighted in the error message more clearly as the cause.

1 post - 1 participant

Read full topic

Retry Policy Options for a Pub/Sub subscription under terraform scripts

Nested blocks throwing error in diagnostics

$
0
0

I have a hcl spec that looks like below

var "variable1" {
  name = "test"
  var "nested_variable1" {
    name = "nested_test"
  }
}

I have Golang struct defined like below

type Variable struct {
  Label    string    `hcl:"x,label"`
  Name     string.   `hcl:"name"`
  Variable *Variable `hcl:"var,block"`
}

I am getting error when the hcl is parsed, what am I missing here ? Appreciate any help on this.

Unexpected "var" block; Blocks are not allowed here.'

1 post - 1 participant

Read full topic

Viewing all 11357 articles
Browse latest View live