See structure of the terraform for context
################### terraform.hcl
InstanceCFG = [
{
"Name" = "instance_0001"
"Alias" = "cookie"
},
{
"Name" = "instance_0002"
"Alias" = "cake"
},
{
"Name" = "instance_0003"
"Alias" = "cupcake"
},
{
"Name" = "instance_0004"
"Alias" = "chocolate"
},
{
"Name" = "instance_0005"
"Alias" = "icecream"
}
]
NLBCFG = [
{
"Name" = "8000-tg"
"Port" = "8000"
"Protocol" = "TCP"
},
{
"Name" = "9000-tg"
"Port" = "9000"
"Protocol" = "TCP"
},
]
################### loadbalancer.tf
resource "aws_lb_target_group" "tg" {
count = length(var.NLBConfig)
name = "${var.NLBConfig[count.index]["Name"]}"
port = "${var.NLBConfig[count.index]["Port"]}"
protocol = "${var.NLBConfig[count.index]["Protocol"]}"
vpc_id = var.VPCID
}
resource "aws_lb_listener" "lb_listener" {
count = length(var.NLBConfig)
load_balancer_arn = aws_lb.lb.arn
port = "${var.NLBConfig[count.index]["Port"]}"
protocol = "${var.NLBConfig[count.index]["Protocol"]}"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg[count.index].arn
}
}
################### autoscalinggroup.tf
# AWS AutoScaling Group
resource "aws_autoscaling_group" "asg" {
count = length(var.ClientConfig)
name = "${var.ClientConfig[count.index]["Name"]}_${local.name_postfix}"
min_size = 1
max_size = 1
desired_capacity = 1
force_delete = true
termination_policies = [ OldestLaunchConfiguration ]
health_check_type = "EC2" # TODO: Change to ELB for Healthchecks
health_check_grace_period = 300
target_group_arns = [ aws_lb_target_group.tg.arn, aws_lb_target_group.tg_wss.arn ] # < Issue HERE!
}
I am able to create two groups of resources separately, 5 ASGs and 3 Target Groups, these numbers will change constantly but I need to make sure X number of ASG instances can join X number of target groups independently of one another, is this even possible?
I find the answer as follow:
Note I am using two count statements in two different resources.
################### loadbalancer.tf
# Consolidate Target Groups ARNs for ASG
data "aws_lb_target_group" "data_tg" {
depends_on = [ aws_lb_target_group.tg ]
count = length(var.NLBCFG)
arn = aws_lb_target_group.tg[count.index].arn
}
################### autoscalinggroup.tf
# AWS AutoScaling Group
resource "aws_autoscaling_group" "asg" {
count = length(var.ClientConfig)
name = "${var.ClientConfig[count.index]["Name"]}_${local.name_postfix}"
min_size = 1
max_size = 1
desired_capacity = 1
force_delete = true
termination_policies = [ OldestLaunchConfiguration ]
health_check_type = "EC2" # TODO: Change to ELB for Healthchecks
health_check_grace_period = 300
target_group_arns = [ data.aws_lb_target_group.data_tg[*].arn ] # < Issue HERE!
}
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 have a resource task which gives the next output:
aws_eks_node_group.managed_workers["es"]:
resource "aws_eks_node_group" "managed_workers" {
ami_type = "AL2_x86_64"
arn = "arn:aws:eks:eu-west-1:xxxxx:nodegroup/EKS/EKS_-nodegroup-CI-es/b2be06b7-e5fe-b346-0e29-ec3f459f7b2c"
capacity_type = "ON_DEMAND"
cluster_name = "EKS_CLuster"
disk_size = 20
id = "EKS:EKS_-API-nodegroup-CI-es"
instance_types = [
"m5.xlarge",
]
labels = {
"autoscalergroup" = "pool"
"lifecycle" = "OnDemand"
}
node_group_name = "worker-node-nodegroup-1"
node_role_arn = "arn:aws:iam::xxxxx:role/EKS_workernode"
release_version = "1.18.9-20210722"
resources = [
{
autoscaling_groups = [
{
name = "eks-xxx-xxx-xx"
},
]
remote_access_security_group_id = "sg-xxxx"
},
]
I'm trying to use the autoscaling_groups.name on this way:
resource "aws_autoscaling_group_tag" "nodetags" {
for_each = aws_eks_node_group.managed_workers
autoscaling_group_name = each.value.resources.autoscaling_groups.name
But I'm not able to access to resources.autoscaling_groups.name with success.. Someone know how to access to this data?
Thanks
resources and autoscaling_groups are both lists.
Use each.value.resources[0].autoscaling_groups[0].name
I have autoscaling group and I need to create an application load balancer for accessing the application this is my two code for autoscaling and application load balancer but I get this issue
autoscaling group
resource "aws_launch_configuration" "OS-Type"{
name_prefix = "OS-Type"
image_id = "ami-0996d3051b72b5b2c"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "Dynamic-IN"{
name = "Dynamic-EC2-instance"
min_size = 1
max_size = 4
desired_capacity = 2
health_check_type = "ELB"
launch_configuration = aws_launch_configuration.OS-Type.name
vpc_zone_identifier = [aws_subnet.P-AV1.id, aws_subnet.P-AV2.id]
target_group_arns="aws_lb.App-lb.name"
lifecycle {
create_before_destroy = true
}
}
Application load balancer
resource "aws_lb_target_group" "Target-group"{
name = "Target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
}
resource "aws_lb" "App-lb"{
name = "Application-load-balancer"
load_balancer_type = "application"
subnets = [aws_subnet.P-AV1.id , aws_subnet.P-AV2.id]
internal = false
}
resource "aws_autoscaling_attachment" "TG-attach" {
autoscaling_group_name = aws_autoscaling_group.Dynamic-IN.id
alb_target_group_arn = aws_lb_target_group.Target-group.arn
}
I get this error
Error: Argument or block definition required
on autoscalling-group.tf line 20, in resource "aws_autoscaling_group" "Dynamic-IN":
20: target_group.arns="aws_lb.App-lb.name"
An argument or block definition is required here. To set an argument, use the
equals sign "=" to introduce the argument value.
I have tried
I have tried aws_lb.App-lb.arns for the target group alos but not working in the both ways
Yes like you suspect there should not quotes there:
target_group_arns="aws_lb.App-lb.name"
and that 'target_group_arns' is a set not a single item: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group#target_group_arns
target_group_arns (Optional) A set of aws_alb_target_group ARNs, for use with Application or Network Load Balancing.
Your code should probably be something like:
resource "aws_autoscaling_group" "Dynamic-IN" {
name = "Dynamic-EC2-instance"
min_size = 1
max_size = 4
desired_capacity = 2
health_check_type = "ELB"
launch_configuration = aws_launch_configuration.OS-Type.name
vpc_zone_identifier = [ aws_subnet.P-AV1.id, aws_subnet.P-AV2.id ]
target_group_arns = [ aws_lb_target_group.Target-group.arn ]
lifecycle {
create_before_destroy = true
}
}
I’m getting the error below, from command AWS_PROFILE=myprofile AWS_REGION=sa-east-1 terraform apply -target=module.saopaulo_service_dev_kubernetes.
Error authorizing security group rule type ingress: InvalidGroup.NotFound: The security group ‘sg-something’ does not exist
The target I'm applying is as below.
module "saopaulo_service_dev_kubernetes" {
source = "./modules/regional-kubernetes"
region_code = "saopaulo"
vpc_name = "main"
env = "dev"
cluster_prefix = "service"
instance_type = "m5.2xlarge"
providers = {
aws = aws.saopaulo
}
}
The source file is as below. I didn't add all the files, as there are too many, but just attached the eks module (terraform-aws-modules/eks/aws) I use to create my module.
data "aws_eks_cluster" "cluster" {
name = module.eks.cluster_id
}
data "aws_eks_cluster_auth" "cluster" {
name = module.eks.cluster_id
}
provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
token = data.aws_eks_cluster_auth.cluster.token
load_config_file = false
version = "~> 1.9"
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "12.2.0" # Version Pinning
cluster_name = local.cluster_name
cluster_version = local.cluster_version
vpc_id = local.vpc_id
subnets = local.private_subnets
cluster_enabled_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
worker_additional_security_group_ids = [aws_security_group.nodeport.id, data.aws_security_group.common_eks_sg.id]
wait_for_cluster_cmd = "for i in `seq 1 60`; do curl -k -s $ENDPOINT/healthz >/dev/null && exit 0 || true; sleep 5; done; echo TIMEOUT && exit 1"
worker_groups = concat([{
instance_type = "t3.micro"
asg_min_size = "1"
asg_max_size = var.asg_max_size
key_name = "shared-backdoor"
kubelet_extra_args = join(" ", [
"--node-labels=app=nodeport",
"--register-with-taints=dedicated=nodeport:NoSchedule"
])
pre_userdata = file("${path.module}/pre_userdata.sh")
tags = concat([for k, v in local.common_tags : {
key = k
value = v
propagate_at_launch = "true"
}], [{
key = "Role"
value = "nodeport"
propagate_at_launch = "true"
}])
}], local.worker_group)
map_users = local.allow_user
# map_roles = local.allow_roles[var.env]
}
I have security group named sg-something in sa-east-1 region, and have also checked that I’m running terraform apply on correct region by checking
data "aws_region" "current" {}
output my_region {
value = data.aws_region.current.name
}
Any suggestions?
I am trying to create resource aws_lb_listener with terraform interpolation for if-else condition. But It says me there is no change in the infrastructure. However, It has not created https listener yet on the infrastructure. Is anything missing in below code ?
alb.tf
resource "aws_lb_listener" "https" {
count = "${var.https_listener_enable == true ? 1 : 0}"
load_balancer_arn = "${aws_lb.main.arn}"
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = "arn:aws:iam::187416307283:server-certificate/test_cert_rab3wuqwgja25ct3n4jdj2tzu4"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = "Nothing is here. Go Away."
status_code = "200"
}
}
}
variables.tf
variable "https_listener_enable" {}
main.tf
module "public_alb" {
source = "../modules/alb"
load_balancer_name = "example-production"
https_listener_enable = true
security_groups = ["${module.security_group.sg_http}"]
load_balancer_is_internal = false
idle_timeout = 60
enable_deletion_protection = false
enable_http2 = true
tags = "${map("Environment", "production",
"Name", "example-production",)}"
subnets = "${module.vpc.public_subnets}"
vpc_id = "${module.vpc.vpc_id}"
}
Replace count = "${var.https_listener_enable == true ? 1 : 0}" with count = "${var.https_listener_enable == "true" ? 1 : 0}" . This should work if you have already defined variable "https_listener_enable" value in .tfvars file or passing from commandline .
Changing count value to this "${var.https_listener_enable ? 1 : 0}" works for me.