Need suggestion.
I am trying to run the below code. First adf is imported which has the vsts configuration.
For second adf, i dont need the vsts configuration. I have tried using dymanic block, but getting error as below.
on main.tf line 16, in resource "azurerm_data_factory" "adf":
2020-12-24T08:13:44.3101544Z 16: dynamic [4m"action"
[0m {
2020-12-24T08:13:44.3101802Z [0m
2020-12-24T08:13:44.3102076Z Blocks of type "action" are not expected here.
Main.tf
resource "azurerm_data_factory" "adf"{
for_each = var.purposes
name=lower("${var.component}-${var.project}-${var.regionname}-${var.azureregion}-${var.environment}-${each.value.purpose}")
location = data.azurerm_resource_group.rg.location
resource_group_name = data.azurerm_resource_group.rg.name
identity{
type="SystemAssigned"
}
dynamic "action" {
for_each = var.vsts_config ? [1] : []
content {
vsts_configuration {
account_name = var.accountname
branch_name = var.branchname
project_name = var.projectname
repository_name = var.repository
tenant_id = "__tenantId__"
root_folder = var.rootfolder
}
}
}
}
input.tfvars
purposes = {
a = {
purpose = "load",
}
b = {
purpose = "live",
}
}
action is not a valid block in azurerm_data_factory. If you want to make vsts_configuration block optional, then you code should be:
dynamic "vsts_configuration" {
for_each = var.vsts_config ? [1] : []
content {
account_name = var.accountname
branch_name = var.branchname
project_name = var.projectname
repository_name = var.repository
tenant_id = "__tenantId__"
root_folder = var.rootfolder
}
}
Related
I have written code that works well in order to create Azure Firewall Network Rules via Terraform. Weeks later i'm asked to add an attribute "expiration" in order to enable users to create temporary network rules.
If the expiration field is 0, means the rule is permanent, if not, i compare the date with the sysdate.
I have tried nearly every possible "for_each" with "for" and "if" combinations, but nothing seems to work. That "expiration" attribute seems inaccessible from outside the loop.
Here are the files of my code:
main.tf
module.tf (edits must be done here, in the dynamic "rule" bloçk of the network_rule_collection block, all other files have been simplified and are here only for better understanding of the code logic)
variables.tf
net_rules.yaml
fw_collections.yaml
Main.tf
locals {
collections = yamldecode(file("../environments/fw_collections.yaml"))
netrules = yamldecode(file("../environments/net_rules.yaml"))
apprules = yamldecode(file("../environments/app_rules.yaml"))
}
module "tdf_az_firewall_policy_rule_collection_group" {
source = "../../modules/tdf_az_firewall_policy_rule_collection_group"
fw_policy_id = module.tdf_az_firewall_policy.firewall_policy_id
fw_c = local.collections.FW_Collections
fw_nr = local.netrules.FW_NET_Rules
fw_ar = local.apprules.FW_APP_Rules
rgname = data.azurerm_resource_group.ipgrg.name
sub = element(split("/", module.tdf_az_virtual_hub_module.virtual_hub_id), 2)
depends_on = [module.tdf_az_firewall_policy, module.tdf_az_firewall]
}
Module.tf
resource "azurerm_firewall_policy_rule_collection_group" "fw-prcg" {
for_each = var.fw_c
name = each.key
firewall_policy_id = var.fw_policy_id
priority = each.value[0]
dynamic "network_rule_collection" {
for_each = { for nr, name in var.fw_nr : nr => name if nr == each.key }
content {
name = each.key
priority = each.value[0]
action = each.value[1]
dynamic "rule" {
for_each = { for x, y in var.fw_nr[each.key] : x => y.expiration if timecmp(y.expiration, timestamp()) == 1 }
content {
name = rule.value.name
protocols = rule.value.protocols
source_ip_groups = [for s in rule.value.source_ip_groups : join("/", ["/subscriptions", var.sub, "resourceGroups", var.rgname, "providers/Microsoft.Network/ipGroups", s])]
destination_ip_groups = [for d in rule.value.destination_ip_groups : join("/", ["/subscriptions", var.sub, "resourceGroups", var.rgname, "providers/Microsoft.Network/ipGroups", d])]
destination_ports = rule.value.destination_ports
}
}
}
}
dynamic "application_rule_collection" {
for_each = { for ar, name in var.fw_ar : ar => name if ar == each.key }
content {
name = each.key
priority = each.value[0]
action = each.value[1]
dynamic "rule" {
for_each = var.fw_ar[each.key]
content {
name = rule.value.name
dynamic "protocols" {
for_each = rule.value.protocols
content {
type = protocols.value.type
port = protocols.value.port
}
}
source_ip_groups = [for s in rule.value.source_ip_groups : join("/", ["/subscriptions", var.sub, "resourceGroups", var.rgname, "providers/Microsoft.Network/ipGroups", s])]
destination_fqdns = rule.value.destination_fqdns
destination_urls = rule.value.destination_urls
terminate_tls = rule.value.terminate_tls
web_categories = rule.value.web_categories
destination_fqdn_tags = rule.value.destination_fqdn_tags
}
}
}
}}
variables.tf
variable "fw_policy_id" {}
variable "fw_c" {}
variable "fw_nr" {}
variable "fw_ar" {}
variable "sub" {}
variable "rgname" {}
netrules.yaml
FW_NET_Rules:
Blacklist-Net:
- name: blacklisted_inbound_ips_rule_inbound
source_ip_groups: ["blacklisted_inbound_ips"]
destination_ip_groups: ["Any-ip"]
estination_ports: ["*"]
protocols: ["Any"]
expiration: 0
- name: k8saas_backlisted_idps_rule_inbound
source_ip_groups: ["k8saas_blacklist_ip_inbound"]
destination_ip_groups: ["Any-ip"]
destination_ports: ["*"]
protocols: ["Any"]
expiration: 0
Mobility:
- name: Mobility-LAN-VNET
source_ip_groups: ["Mobility-LAN"]
destination_ip_groups: ["Mobility-VNET"]
destination_ports: ["443"]
protocols: ["TCP"]
expiration: "2022-12-12T00:00:00Z"
- name: Mobility-LAN-To-Data
source_ip_groups: ["Mobility-LAN"]
destination_ip_groups: ["Data-VNET"]
destination_ports: ["443"]
protocols: ["TCP"]
expiration: "2022-12-12T00:00:00Z"
fw_collections.yaml
FW_Collections:
Blacklist-Net: [100, "Deny"]
Mobility: [105, "Allow"]
I am fairly new to terraform and trying to create a google_compute_backend_service using terraform and there are multiple backend blocks inside the resource as shown below:
resource "google_compute_backend_service" "app-backend" {
log_config {
enable = "true"
sample_rate = "1"
}
name = "app-backend"
port_name = "http-34070"
project = "my-project"
protocol = "HTTP"
session_affinity = "NONE"
timeout_sec = "30"
backend {
group = "insatnce-group1"
}
backend {
group = "instance-group2"
}
backend {
group = "instance-group3"
}
health_checks = [google_compute_http_health_check.app-http-l7.name]
}
As seen in the code block above the backend block repeats multiple times. I want to make it dynamic so I do not have to write multiple blocks manually.
I tried the following:
Created a variable in the variables.tf file that contains all the instance groups:
variable "groups" {
type = list(object({
name = string
}))
default = [{ name = "instance-group1"},
{ name = "instance-group2"},
{ name = "instance-group3"}]
}
And modified my resource block to this:
resource "google_compute_backend_service" "app-backend" {
log_config {
enable = "true"
sample_rate = "1"
}
name = "app-backend"
port_name = "http-34070"
project = "my-project"
protocol = "HTTP"
session_affinity = "NONE"
timeout_sec = "30"
dynamic "backend" {
for_each = var.groups
iterator = item
group = item.value.name
}
health_checks = [google_compute_http_health_check.app-http-l7.name]
}
However, when I execute terraform plan I get the following error:
Error: Unsupported argument
│
│ on backend_service.tf line 15, in resource "google_compute_backend_service" "app-backend":
│ 15: group = item.value.name
│
│ An argument named "group" is not expected here.
Where am I going wrong? Is there a better way to achieve this?
You can check the dynamic blocks documentation for the syntax. Otherwise, you had the right idea.
dynamic "backend" {
for_each = var.groups
content {
group = backend.value.name
}
}
You can also simplify the variable structure to make this even easier.
variable "groups" {
type = set(string)
default = ["instance-group1", "instance-group2", "instance-group3"]
}
dynamic "backend" {
for_each = var.groups
content {
group = backend.value
}
}
I have a terraform file with the following contents:
resource "aws_iam_group" "developers" {
name = each.value
for_each = toset(var.groups)
}
resource "aws_iam_group_membership" "developers_team" {
name = "Developers Team"
users = [each.value]
for_each = toset(var.group_users)
group = aws_iam_group.developers.name
}
I would like to reference aws_iam_group from aws_iam_group_membership. How would I do that? The current terraform file is not working.
I tried this:
group = aws_iam_group.developers[each.value] //This will not work since it uses the for_each of
its own code block
The variable file is as below:
variable "groups" {
type = list(string)
default = [
"terraform_group1",
"terraform_group2",
"terraform_group3",
]
}
variable "group_users" {
type = list(string)
default = [
"terraform_test_user1",
"terraform_test_user2"
]
}
Edit:
I tried the below, but it is not working
resource "aws_iam_group_membership" "developers_team" {
name = "Developers Team"
users = [for group_user in var.group_users : group_user]
for_each = toset(var.groups)
group = aws_iam_group.developers[each.key]
}
Apparently, this is working:
resource "aws_iam_group" "developer" {
name = "truedeveloper"
}
resource "aws_iam_group_membership" "developers_team" {
name = "Developers_Team"
users = [for group_user in var.group_users : group_user]
for_each = toset(var.groups)
group = aws_iam_group.developer.name
}
this code has worked before, all I'm trying to do is add new frontend endpoints, routing rules, backend pools
I've tried only sharing the code snippets that I think are relevant but let me know if there's some key info you need missing
This one has stumped me for a couple days now and no matter what I've tried I cannot seem to make sense of the error. Its like its indexing out of the variable or searching for something that isn't there but there are something like 6 already there and now I'm adding another.
I'm worried that this front door code has not been ran in awhile and something has gotten screwed up in state. Especially given all the alerts on the accompanying TF docs for this resource - https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/frontdoor_custom_https_configuration
Its been quite awhile but the AzureRM version has gone through several updates - possibly from previous to 2.58 to now past 2.58. I guess I also don't know how to verify/look at the state file and ensure its correct - even looking at the 2.58 upgrade notes its just confusing.
Ideas?
The error
on ..\modules\frontdoor\main.tf line 129, in resource "azurerm_frontdoor_custom_https_configuration" "https_config":
129: frontend_endpoint_id = azurerm_frontdoor.main.frontend_endpoints[each.value]
|----------------
| azurerm_frontdoor.main.frontend_endpoints is map of string with 8 elements
| each.value is "www-sell-dev-contoso-com"
The given key does not identify an element in this collection value.
main.tf
provider "azurerm" {
features {}
}
terraform {
backend "azurerm" {
}
}
#the outputs.tf on this module output things like the frontdoor_endpoints
#the outputs.tf with main.tf also output similar values
module "coreInfraFrontDoor" {
source = "../modules/frontdoor"
resource_group_name = module.coreInfraResourceGroup.resource_group_name
frontdoor_name = "fd-infra-${terraform.workspace}-001"
enforce_backend_pools_certificate_name_check = lookup(var.enforce_backend_pools_certificate_name_check, terraform.workspace)
log_analytics_workspace_id = module.coreInfraLogAnalytics.log_analytics_workspace_id
tags = local.common_tags
health_probes = lookup(var.health_probes, terraform.workspace)
routing_rules = lookup(var.routing_rules, terraform.workspace)
backend_pools = lookup(var.backend_pools, terraform.workspace)
frontend_endpoints = lookup(var.frontend_endpoints, terraform.workspace)
prestage_frontend_endpoints = lookup(var.prestage_frontend_endpoints, terraform.workspace)
frontdoor_firewall_policy_name = "fdfwp${terraform.workspace}001"
frontdoor_firewall_prestage_policy_name = "fdfwp${terraform.workspace}prestage"
mode = lookup(var.mode, terraform.workspace)
ip_whitelist_enable = lookup(var.ip_whitelist_enable, terraform.workspace)
ip_whitelist = lookup(var.ip_whitelist, terraform.workspace)
key_vault_id = module.coreInfraKeyVault.id
}
module main.tf
resource "azurerm_frontdoor" "main" {
name = var.frontdoor_name
location = "global"
resource_group_name = var.resource_group_name
enforce_backend_pools_certificate_name_check = var.enforce_backend_pools_certificate_name_check
tags = var.tags
dynamic "routing_rule {#stuff is here obv}
dynamic "backend_pool {#also here}
#i think this is because there was an issue/needs to be some default value for the first endpoint?
frontend_endpoint {
name = var.frontdoor_name
host_name = "${var.frontdoor_name}.azurefd.net"
web_application_firewall_policy_link_id = azurerm_frontdoor_firewall_policy.main.id
}
#now the dynamic ones from vars
dynamic "frontend_endpoint" {
for_each = var.frontend_endpoints
content {
name = frontend_endpoint.value.name
host_name = frontend_endpoint.value.host_name
session_affinity_enabled = lookup(frontend_endpoint.value, "session_affinity_enabled", false)
web_application_firewall_policy_link_id = azurerm_frontdoor_firewall_policy.main.id
}
}
versions.tf
terraform {
required_version = "~> 0.14.7"
required_providers {
azurerm = "~>2.72.0"
}
}
variables.tf
variable "frontend_endpoints" {
type = map(any)
description = "List of frontend (custom) endpoints. This is in addition to the <frontend_name>.azurefd.net endpoint that this module creates by default."
default = {
dev = [
{
name = "dev-search-contoso-com"
host_name = "dev.search.contoso.com"
},
{
name = "dev-cool-contoso-com"
host_name = "dev.cool.contoso.com"
},
########################
#this is new below
########################
{
name = "dev-sell-contoso-com"
host_name = "dev.sell.contoso.com"
}
]
prod = [ #you get the idea ]
}
am trying to deploy the azure notification hub using terrafrom.
while integrating the google API token, if the token does not exist deployment is going to fail.
want deploy the notification hub with out the token for that using dyanamic block.
dynamic gcmcred {
for_each = var.gcm_api == null ? [] : [ "dummy" ]
content {
gcm_credential {
api_key = var.gcm_api.token
}
}
}
below mentioned way declared the variable
variable "gcm_api" {
type = list(string)
default = [ "null" ]
}
am getting an issue like un supported block type
Try to do it this way:
main.tf
locals {
enable_gcm_credential = var.enable_gcm_credential ? [1] : []
}
resource "azurerm_notification_hub" "notification_hub" {
name = var.name
namespace_name = var.namespace_name
resource_group_name = var.resource_group_name
location = var.location
dynamic "gcm_credential" {
for_each = local.enable_gcm_credential
content {
api_key = var.api_key
}
}
}
variables.tf
variable "enable_gcm_credential" {
type = bool
default = false
}
...