text:
Terminus 3.0 compatibility

When the plugin is installed with the terminus 3 command (terminus self:plugin:install terminus-plugin-project/terminus-pancakes-plugin ), every subsequent terminus command generates multiple PHP warnings:
PHP Warning:  include(/Users/jmann/.terminus/terminus-dependencies-2512c16/vendor/terminus-plugin-project/terminus-pancakes-plugin/src/Commands/../../vendor/autoload.php): failed to open stream: No such file or directory in /Users/jmann/.terminus/terminus-dependencies-2512c16/vendor/terminus-plugin-project/terminus-pancakes-plugin/src/Commands/PancakesCommand.php on line 13

The plugin still works as expected without this include statement, so I propose simply removing it.

I'm guessing that this was included for Terminus 1 (or Terminus 0?) compatibility. It would be best to remove it now, as those old Terminus versions are no longer supported on the Pantheon platform.

@jeffm2001:  Good call!  Thank you for the confirmation @greg-1-anderson.

license: MIT


text:
not recovering properly from invalid document in dashboard

Follow the 'my first TerminusDB' example until you have the schema

make a person.  Fill in the id doc:twice
and make a friend doc:nonexist

Click Save
EXPECTED: error message
OBSERVED: no reaction

click Save again
EXPECTED: ????
OBSERVED: NOW I get an error message - the message refers to the root of the document space, and generally is unhelpful

1 Violation Detected in Document
vio:UntypedInstanceThe subject 'http://localhost:6363/annie/document/foo' has no defined class.
vio:subjecthttp://localhost:6363/annie/document/foo

This no longer applies - refers to version 1.0 frame code

source: gharchive/issue

authors: Anniepoo kevinchekovfeeney

repo: terminusdb/terminusdb-server

license_type: permissive

license_source: github-api


text:
Fix error executing in chroot in Ubuntu container

When Tern ran in a Ubuntu container for images with an apk package
manager, there was an issue finding the shell which led to a failed
package metadata command using chroot.
This commit adds a workaround to make sure Tern can find a shell when
running in a Ubuntu container, specifically when the shell is symlinked
to busybox for the container being analyzed. A more detailed description
of the problem can be found in the bug report[1].
It's unclear exactly why the realpath fails to resolve to the correct
utility location when Tern runs in a Ubuntu container while analyzing
apk-based container images. For now, this commit is meant as a
workaround for this exceptional case that is blocking several users.
[1]https://github.com/tern-tools/tern/issues/1161
Resolves #1161
Signed-off-by: Rose Judge rjudge@vmware.com

Tested by @jeeppler in https://github.com/tern-tools/tern/issues/1161. Merging.

source: gharchive/pull-request

repo: tern-tools/tern


text:
🛑 TransTurin Website is down

In cb87eb5, TransTurin Website (https://www.transturin.com) was down:

HTTP code: 0
Response time: 0 ms

Resolved: TransTurin Website is back up in 066610d.

repo: terorero/monitor


text:
More than one attach target in target groups

Is your request related to a problem? Please describe.
In module version 8.x was option targets in target_groups configuration, for attach destination target or targets. In new 9.x module, as I understand, I can configure only 1 target per target group.
Describe the solution you'd like.
I need to attach few targets (servers) in 1 target group (fro HA configuration), so I would appreciate if you will add option for attach more than 1 destination in target group.

The recommendation there for HA would be to attach an autoscaling group

@bryantbiggs  Could you give an example how this could be done? I've tried using an ASG ID and arn for target_id but both were rejected. Example shows using ARN:
  target_groups = {
    instance_http = {
      name_prefix      = "http-"
      backend_protocol = "TCP"
      backend_port     = 32080
      port             = 32080
      protocol         = "TCP"
      target_type      = "instance"
      target_id        = var.AUTOSCALING_GROUP_ARN
    }
}

│ Error: registering targets with target group: ValidationError: Instance ID 'arn:aws:autoscaling:eu-central-1:<account-id>:autoScalingGroup:c4b71856-026e-43f9-bdc1-3b34dfed9a19:autoScalingGroupName/base_arm64-prod-2023020409180057890000000e' is not valid
│       status code: 400, request id: 00a780e5-6fc1-482b-9c78-a20e3859987b
│
│   with module.nlb_prod.module.load_balancer.aws_lb_target_group_attachment.this["instance_http"],
│   on .terraform/modules/nlb_prod.load_balancer/main.tf line 507, in resource "aws_lb_target_group_attachment" "this":
│  507: resource "aws_lb_target_group_attachment" "this" {

I also checked in the AWS console how this would work, but couldn't get it going for an ASG there either.

ah, I didn't realize it was a separate resource. We'll need to add it https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_attachment

Hi @bryantbiggs, many thanks for the huge contribution towards converting from lists to maps; sure there's some nesting, but the target_group_key is great a addition for maintenance and legibility.
In the same vein as @pat-s, I'm looking to attach N-number of targets to a group: specifically, ECS Fargate instances. With module/alb v8, it was possible to simply forward a listener to a target group with target_type = "ip", as demonstrated in module/ecs v5.
Whereas, with module/alb v9, I'm not sure what to pass as the target_id for the target group❔ This is further compounded by module/ecs v5 requiring load_balancer = { service = { target_group_arn = ... } }, so it needs to be provisioned after the alb. Unless there's a way to pass the capacity provider's ID without creating a circular dependency?
Thanks for your time.

The recommendation there for HA would be to attach an autoscaling group

In many places we don't have autoscaling group, but configuration is like that:
module "ec2_servers" {
  source  = "terraform-aws-modules/ec2-instance/aws"

  for_each = toset(["0", "1", "2"])
  ...
}

and in previous module version I configured it like that:
targets = {
        for i, server in module.ec2_servers :
        i => {
          target_id = server.id
          port      = 80
        }
      }

Is there any other way to configure it?
Thank you

@rdhar I've updated the ECS module to use the latest ALB module and demonstrate how these two modules integrate https://github.com/terraform-aws-modules/terraform-aws-ecs/pull/130
Next, I'm working on updating the autoscaling module to add the target group attachment resource

traffic source attachment for autoscaling groups is being added here https://github.com/terraform-aws-modules/terraform-aws-autoscaling/pull/248 - please see the updated example in that PR for how to target an autoscaling group from the LB

@bryantbiggs AFAIU the update example is linked to the use of terraform-aws-autoscaling. Is there a way to use the nlb module with a standalone ASG? In my case, the ASG are created through aws-terraform-eks and I can't infer how I can add such an ASG to a target_group in this module.
A quick snippet for this would be highly appreciated, we're still operating on a hardcoded workaround right now.

When using EKS, my first recommendation would be to use the AWS load balancer controller. You can let it create all of the LB resources, or you can create a standalone LB and use the target group attachment only functionality

@rdhar I've updated the ECS module to use the latest ALB module and demonstrate how these two modules integrate terraform-aws-modules/terraform-aws-ecs#130

@bryantbiggs Huge thanks once again for sharing those examples, since they're crucial while we're working with Math B (@ROunofF) to optimize our ECS Fargate deployment with TF AWS modules. As we migrate various Node/Python microservices to ECS, attaching each one's target group to the same ALB is the ideal goal.
Now, we've run into a problem with paths. To share more context, there are services A, B, and C that are now routed by forwarder listener rules to the appropriate target group. But all of these are services route at the "root"-level. In other words, URLs like /health and /docs exist for each service, such as: A/health, B/health, C/api/docs nested paths, etc.
However, the ALB listener rule appears to only be able to forward one level, so it's unable to serve any of target groups other than the default. Here's the specific rule configuration for reference, where I've tried both with and without wildcard *.
conditions = [{ path_pattern = {
                values = ["/${local.srvA}/*"]
             }}]
actions    = [{
                type = "forward"
                target_group_key = local.srvA
             }]

Am I missing something obvious that'd allow me to serve all of service A's endpoints under example.org/A/health, then example.org/C/api/docs, and so forth?

When using EKS, my first recommendation would be to use the AWS load balancer controller. You can let it create all of the LB resources, or you can create a standalone LB and use the target group attachment only functionality

Thanks. We'll consider the LB controller for upcoming clusters.
For the current one however, we're now stuck with NLB and the need to reference ASG from the terraform-aws-eks module.

use the target group attachment only functionality

Could you link to an example here? I've tried searching all docs and examples but I can't figure out how I can dynamically link an ASG to a target_group with type: instance in NLB v9. If this is not possible at all, this would already be a helpful information.

Hi there,
First of all thanks for the conversion from lists to maps. That's a huge progress IMHO and I hope this will be done in many other aws tf modules.
I'm also in the need to have several instance targets in a target group and no possibility to add these instances into a ASG.
So until this is possible I forked your module to proceed as below.
Notes:

var target_groups ==> target_group_map in my code
add a new vars target_group_instance_attachment_map  defined as below

# Instance | ECS Container
variable "target_group_instance_attachment_map" {
  description = "Map of target group attachment configurations to create"
  type = map(object({
    availability_zone = optional(string, null) # The Availability Zone where the IP address of the target is to be registered. If the private IP address is outside of the VPC scope, this value must be set to all.
    port              = optional(string, null) # The port on which targets receive traffic.
    protocol          = optional(string, null) # The protocol on which targets receive traffic.
    target_arn        = optional(string, null) # The ARN of the target group with which to register targets.
    target_id         = optional(string, null) # The Instance ID, or the container ID of the target.
  }))
  default = {}
}

add a new vars target_group_ip_attachment_map  defined as below

# IP Address
variable "target_group_ip_attachment_map" {
  description = "Map of target group attachment configurations to create"
  type = map(object({
    availability_zone = optional(string, null) # The Availability Zone where the IP address of the target is to be registered. If the private IP address is outside of the VPC scope, this value must be set to all.
    port              = optional(string, null) # The port on which targets receive traffic.
    protocol          = optional(string, null) # The protocol on which targets receive traffic.
    target_arn        = optional(string, null) # The ARN of the target group with which to register targets.
    target_id         = optional(string, null) # The IP address of the target.
  }))
  default = {}
}

add a new vars target_group_lambda_attachment_map  defined as below

# Lambda
variable "target_group_lambda_attachment_map" {
  description = "Map of target group attachment configurations to create"
  type = map(object({
    availability_zone = optional(string, null) # The Availability Zone where the IP address of the target is to be registered. If the private IP address is outside of the VPC scope, this value must be set to all.
    port              = optional(string, null) # The port on which targets receive traffic.
    protocol          = optional(string, null) # The protocol on which targets receive traffic.
    target_arn        = optional(string, null) # The ARN of the target group with which to register targets.
    target_id         = optional(string, null) # The Lambda function ARN of the target.
  }))
  default = {}
}

add a new vars target_group_alb_attachment_map  defined as below

# ALB
variable "target_group_alb_attachment_map" {
  description = "Map of target group attachment configurations to create"
  type = map(object({
    availability_zone = optional(string, null) # The Availability Zone where the IP address of the target is to be registered. If the private IP address is outside of the VPC scope, this value must be set to all.
    port              = optional(string, null) # The port on which targets receive traffic.
    protocol          = optional(string, null) # The protocol on which targets receive traffic.
    target_arn        = optional(string, null) # The ARN of the target group with which to register targets.
    target_id         = optional(string, null) # The ALB ARN of the target.
  }))
  default = {}
}

Add the following local
locals {
target_group_attachment_map = merge(
    { # Instance ID | ECS Container ID
      for k, v in var.target_group_instance_attachment_map : k => merge(
        v,
        {
          target_group_arn = [
            for tg in aws_lb_target_group.this : tg.arn if tostring(tg.port) == v.port && tg.protocol == v.protocol
          ][0]
        }
      )
    },
    { # IP address
      for k, v in var.target_group_ip_attachment_map : k => merge(
        v,
        {
          target_group_arn = [
            for tg in aws_lb_target_group.this : tg.arn if tostring(tg.port) == v.port && tg.protocol == v.protocol
          ][0]
          target_id = join(",", data.dns_a_record_set.this[k].addrs)
        }
      )
    },
    # didn't tested the 2 next options so there are commented in my local
    # { # Lambda ARN
    #   for k, v in var.target_group_lambda_attachment_map : k => merge(
    #     v,
    #     {
    #       target_group_arn = [
    #         for tg in aws_lb_target_group.this : tg.arn if tostring(tg.port) == v.port && tg.protocol == v.protocol
    #       ][0]
    #       target_id = join(",", dns_a_record_set.this.addrs)
    #     }
    #   )
    # },
    # { # ALB ARN
    #   for k, v in var.target_group_alb_attachment_map : k => merge(
    #     v,
    #     {
    #       target_group_arn = [
    #         for tg in aws_lb_target_group.this : tg.arn if tostring(tg.port) == v.port && tg.protocol == v.protocol
    #       ][0]
    #       target_id = join(",", dns_a_record_set.this.addrs)
    #     }
    #   )
    # },
}

The resource 'Target Group Attachment' is set as below
################################################################################
# Target Group Attachment
################################################################################

resource "aws_lb_target_group_attachment" "this" {
  depends_on = [
    aws_lb_target_group.this,     # I'm not sure this dependancy is really needed since it is set in my local.
    aws_lambda_permission.this
  ]
  for_each = {
    for k, v in local.target_group_attachment_map :
    k => v if local.create && lookup(v, "create_attachment", true)
  }

  # target_group_arn  = aws_lb_target_group.this[each.key].arn
  target_group_arn  = each.value.target_group_arn
  target_id         = each.value.target_id
  port              = try(each.value.target_type, null) == "lambda" ? null : try(each.value.port, var.default_port)
  availability_zone = try(each.value.availability_zone, null)

}

I hope this could help to be added in an official feature in order I could use this module and not my fork anymore.

need to have several instance targets in a target group and no possibility to add these instances into a ASG

I am curious, and want to better understand - why the need for standalone instances like this?

The solution is provided by an editor which does not allow to work with ASG.
This is not a solution that I approve but I needed this to be available quickly so I didn't have the time to look for a better option for now.

I'm open to hear other use cases but so far all of the feedback and data I've collected has pointed to this being an edge case where "modern practices" are not utilized. Therefore, I think the workaround for these edge cases, if necessary, is to let this module create the target group but without any attachments create_attachment = false, and then use the aws_lb_target_group_attachment resource to make the necessary attachments. You can do 1:1, use for_each, etc., its up to you and your use case. This saves the hassle of all of the iterating deconstructing and re-constructing of mappings to make the attachments (KISS). Something like below:
module "alb" {
  source  = "terraform-aws-modules/alb/aws"
  version = "~> 9.0"

  # Truncated ...

  target_groups = {
    example = {
      backend_protocol = "HTTP"
      backend_port     = 80
      target_type      = "instance"

      # Attachments will be made externally
      create_attachment = false
    }
  }
}

resource "aws_lb_target_group_attachment" "external" {
  for_each = {for k,v in aws_instance.example: k => v}

  target_group_arn = module.alb.target_groups["example"].arn
  target_id        = each.value.id
  port             = 80
}

resource "aws_instance" "example" {
  for_each = toset(["1", "2", "3"]) # ¯\_(ツ)_/¯

  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
}

While it's in the context of ECS Fargate instances instead of EC2, but here's a working snippet to demo for-each loop of target_groups directly within ALB module, like so:
locals {
  services = [
    { name = "alpha"
      port = 80 },
    { name = "bravo"
      port = 80 },
  ]}

target_groups = {
  for service in local.services : service.name => {
    name              = service.name
    backend_port      = service.port
    target_type       = "ip"
    create_attachment = false
}}

@bryantbiggs
Another valid use case for myself is to create a private ALB that targets VPC endpoint IP addresses, such a scenario is sometimes needed in private networks to handle TLS properly on internal CA certificates and custom private domains, in that case, targets would be bare multiple IP addresses. Currently, there is a big limitation in the module that can be handled by a workaround.
Another use case is for hybrid cloud environments which also would require IP targets.

edge case where "modern practices" are not utilized

Unfortunately in my cases ("IP" target usage) to my current knowledge cannot be solved assuming we still use AWS ELBs so, for me those are not edge cases and I would call them just valid but very rare use cases.

@bryantbiggs
This module upgrade broke us as well.  We are required per our accreditation to require all traffic to be encrypted, and to have a LB sandwich.  We also require being able to push traffic to 1 of 2 EKS clusters

1 Public VPC, with a Public ALB, Fronted by an AWS WAF.
2 Private VPC's, each with an EKS cluster, with NGINX ingress creating a private NLB.
Create VPC Endpoints For each IP/AZ of each Private NLB created by NGINX Ingress
Weighted Route 443 on the Public ALB to 1 of the 2 Private NLB's depending on which cluster is active

      targets = {
        nlb1 = {
          port      = 443
          target_id = data.aws_network_interface.nlb0.private_ip
        }
        nlb2 = {
          port      = 443
          target_id = data.aws_network_interface.nlb1.private_ip
        }
        nlb3 = {
          port      = 443
          target_id = data.aws_network_interface.nlb2.private_ip
        }
      }

I know this is not an edge case, since its the 3rd place I've been at that handled Blue/Green Clusters this way.

I'm sorry, what exactly is the issue in the example above?

In the previous version of the module, a target group, could have multiple targets defined, in the new version of the module, it does not appear, from what I can tell, that you can attach more than 1 target to a target group.  I cant use your ASG suggestion etc, since our targets are the IP's of the VPC endpoints for the private NLB's.

Ah ok, stating This module upgrade broke us as well. is not quite accurate if I understand correctly - its just that the previous behavior is not carried over to the current module.
In that scenario, if we ignore the number of ways that could break due to the dynamic nature of endpoints and IPs 😅  - does the configuration you provided not work for your use case? Is it merely just trying to avoid multiple target groups?
There is the alternate route where you can create the attachment as well - similar to the relationship between this module and the ECS module. You would have this module create the target group, but no attachments - and then you can use the attachment resource to attach the appropriate IDs in the fashion of your chosing

Moving to multiple TG's would require a re-accreditation of the system topology.  So we dont have any choice but to re-create the attachments outside of the module.
I was simple demonstrating that, stating edge case where "modern practices" are not utilized is not quite accurate

A load balancer that can only attach one instance and not "load balance" between multiple instances does not seem like an edge case in any way.  It is not an LB, it's an SSL termination for one ec2.  You might want to poll the user base before making such changes in the future.

A load balancer that can only attach one instance and not "load balance" between multiple instances does not seem like an edge case in any way. It is not an LB, it's an SSL termination for one ec2. You might want to poll the user base before making such changes in the future.

How do you suggest we poll the user base? The refactoring PR was opened in August and closed in October, that seems like plenty of time for feedback, no?
You can attach multiple instances - you just can't do it direct to multiple instances natively in this module. You will need to either use an ASG and load balance traffic over container of instances, or you can use the attachement resource yourself to attach the long lived instances

I guess I will start following these more closely looking for such changes that are not backwards compatible.
It seems you traded a "hassle deconstructing mappings" inside the module for "hassle deconstructing mappings" outside the module in my .tf file.

Was just frustrating to run into, I'm sure you can understand.

changes that are not backwards compatible

That is the definition of a breaking change, FYI.

It seems you traded a "hassle deconstructing mappings" inside the module for "hassle deconstructing mappings" outside the module in my .tf file. Was just frustrating to run into, I'm sure you can understand.

Not exactly - and I'll go back to my previous comment. Trying to treat IPs or instances today as pets is not the norm and therefore thats an edge case. We design things for the norm - for the majority of the population. I didn't see any reasoning from yourself as to why you need to map direct to an instance, but those reasons today are dwindling. Even to @jseiser use case (not that his 👎🏽 adds to this conversation) - the load balancer sandwich architecture is a legacy artifact. If you have business requirements that stipulate this, fine, but we cannot satisfy all requests - we aim to satisfy the majority. For those we can't satisfy, we have provided guidance and alternative solutions. Its just frustrating that something that is provided for free - FREE - and people have the audacity to complain and state demands

For those we can't satisfy, we have provided guidance and alternative solutions.
Your guidance and alternative solution worked, thank you for providing it.
I can appreciate where you are coming from and I may have read intention that was not there, which is hard to gauge in a written medium, I apologize.  You are correct that this is a legacy way of doing things and I will have to figure out a way to make the application move forward and be less pet-like.

module "alb" {
  source  = "terraform-aws-modules/alb/aws"
  version = "~> 9.0"

  # Truncated ...

  target_groups = {
    example = {
      backend_protocol = "HTTP"
      backend_port     = 80
      target_type      = "instance"

      # Attachments will be made externally
      create_attachment = false
    }
  }
}

resource "aws_lb_target_group_attachment" "external" {
  for_each = {for k,v in aws_instance.example: k => v}

  target_group_arn = module.alb.target_groups["example"].arn
  target_id        = each.value.id
  port             = 80
}

resource "aws_instance" "example" {
  for_each = toset(["1", "2", "3"]) # ¯\_(ツ)_/¯

  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
}

I guess this solution to have create_attachment = false  is not yet implemented?
i receive the following error if trying to use that
ValidationError: A target group ARN must be specified

It definitely worked for me, not sure if there is a "listener" section under your Truncated bit, but that is necessary I believe.  I'll grab my config and sanitize it for posting here.

`module "example_nlb" {
source = "../../modules/lb/"
name = "example-nlb"
load_balancer_type    = "network"
vpc_id                = module.vpc.vpc_id
listeners = {
example = {
port            = 51400
protocol        = "TLS"
certificate_arn = module.example_cert.acm_certificate_arn
forward = {
target_group_key = "example_zero"
}
}
}
target_groups = {
example_zero = {
name                 = "example-tg"
protocol             = "TCP"
port                 = 51400
target_type          = "instance"
deregistration_delay = 10
  # Attachments will be made externally
  create_attachment = false
	}
}

}
}
resource "aws_lb_target_group_attachment" "example" {
for_each = {for k,v in module.ec2_example: k => v}
target_group_arn = module.example_nlb.target_groups["example_zero"].arn
target_id        = each.value.id
port             = 51400
}`

I see, yeah, that is what i was doing now, i guess you need to create one target group at least with the module, and additional ones outside the module.  👍

i guess you need to create one target group at least with the module, and additional ones outside the module.

No - the only requirement from a listener is that there is a default action. I don't know what you are trying to do since not a lot of details are provided, but if you are forwarding to a target group, you can forward to one the module creates or an external target group

edge case where "modern practices" are not utilized

https://aws.amazon.com/blogs/networking-and-content-delivery/hosting-internal-https-static-websites-with-alb-s3-and-privatelink/  barely a year old pattern presented by AWS themselves which requires multiple IP targets in a single target group.  This would have worked fine in the previous module version, but now the create_attachment = false workaround is needed.

Hi,
Same for us, this module upgrade broke us as well. We could have more than 1 EC2 to attach to the same TG. Sometimes we cannot use ASG.
Thanks

IMO, users should have the option to pass in a list of targets for a target group. Here's my use case:
aws-load-balancer-controller in EKS is creating an NLB for Nginx in one account. We need an ALB in another account that forwards traffic to these NLB IPs. The only option for us is to pass a list of NLB IPs to the target group.
I'm fully aware this is far from ideal but it seems to me to be a relatively generic use case for multi-account, multi-EKS cluster setups with the need for a single ingress in a different account (ie, we can't just have the aws-load-balancer-controller create our ALB).
To make things more challenging, we are using Terragrunt, whose base unit is a module. This means we need to create and manage our own custom module that follows the work around that has been proposed. It's not as simple as adding another resource for us, unfortunately

IMO, users should have the option to pass in a list of targets for a target group

Go ahead, try to figure that one out

IMO, users should have the option to pass in a list of targets for a target group

Go ahead, try to figure that one out

We can add an optional targets key to the target_groups variable:
target_groups = {
    ex-instance = {
      name_prefix      = "h1"
      protocol         = "HTTP"
      target_type      = "ip"
      port = "80"

      targets          = [{
        target_id        = "10.0.0.0"
      },
      {
        target_id        = "10.0.0.1"
      },
      {
        target_id        = "10.0.0.2"
      }]
    }
  }

Add a locals block and modify the aws_lb_target_group_attachment.this resource:
locals {
  target_group_attachments = flatten([
    for tg_name, tg in var.target_groups : concat(
      # If 'targets' is provided, use it
      [for target in lookup(tg, "targets", []) : {
        tg_name           = tg_name
        target_type       = tg.target_type
        target_id         = target.target_id
        port              = try(target.port, try(tg.port, null))
        availability_zone = try(target.availability_zone, try(tg.availability_zone, null))
      }],
      # If 'targets' is not provided, but 'target_id' is, use 'target_id'
      length(lookup(tg, "targets", [])) == 0 && try(tg.target_id, "") != "" ? [{
        tg_name     = tg_name
        target_type = tg.target_type
        target_id   = tg.target_id
        port        = try(tg.port, null)
        availability_zone = try(tg.availability_zone, null)
      }] : []
    )
  ])
}

resource "aws_lb_target_group_attachment" "this" {
  count = local.create ? length(local.target_group_attachments) : 0

  target_group_arn  = aws_lb_target_group.this[local.target_group_attachments[count.index].tg_name].arn
  target_id         = local.target_group_attachments[count.index].target_id
  port              = try(local.target_group_attachments[count.index].target_type, null) == "lambda" ? null : try(local.target_group_attachments[count.index].port, var.default_port)
  availability_zone = try(local.target_group_attachments[count.index].availability_zone, null)

  depends_on = [aws_lambda_permission.this]
}

For a diff, view the MR here: https://github.com/joshsizer/terraform-aws-alb/pull/1/files
I've tested this in my own Terragrunt project, but I'd be happy to make an MR into this repo and do the appropriate testing with the examples directory if this is an acceptable solution.

we are not changing from for_each back to count - that would be a no go

we are not changing from for_each back to count - that would be a no go

I'd be happy to rework this by changing the targets variable to be a map instead of array, like so:
target_groups = {
        ex-instance = {
            name_prefix      = "h1"
            protocol         = "HTTP"
            target_type      = "ip"

            targets = {
                "target_1" = {
                    target_id = "10.0.0.0"
                },
                "target_2" = {
                    target_id = "10.0.0.1"
                },
                "target_3" = {
                    target_id = "10.0.0.2"
                }
            }
        }
    }

Of course, there would now be a 1:n mapping of target group attachments to target groups, so the keys used in the for each would have to combine the target group name and the target name.
Targets don't have names in AWS, so I'm not sure a map would make sense here in general, however if that's your main stipulation  I'd be happy to rewrite this using for_each.

@joshsizer I think toset() could help with having list of targets instead of map and still using foreach
for_each = toset(local.array_with_unique_items)

however if that's your main stipulation I'd be happy to rewrite this using for_each

I don't have any stipulations per se, but we just did a refactor to move from count to for_each based on a number of known challenges and issues with the prior approach. So I don't think it make sense to go backwards - plus this would be a breaking change as well
I also want to highlight that the solution thats been proposed will only work if users pass each value statically - you cannot use toset() or loop over and unpack results from a data source - keys in any map cannot be dynamic

I also want to highlight that the solution thats been proposed will only work if users pass each value statically - you cannot use toset() or loop over and unpack results from a data source - keys in any map cannot be dynamic

After some testing I understand the issue that you're getting at. We could do something similar to how each listener references a target group:
additional_target_group_attachments = {
  ex-instance-target-1 = {
    target_group = "ex-instance"
    target_id    = "10.0.0.70"
  }
  ex-intance-target-2 = {
    target_group = "ex-instance"
    target_id    = "10.0.0.71"
  }
}

resource "aws_lb_target_group_attachment" "additional_target_group_attachments" {
  for_each = { for k, v in var.additional_target_attachments : k => v if local.create }

  target_group_arn  = aws_lb_target_group.this[each.value.target_group].arn
  target_id         = each.value.target_id
  port              = try(each.value.target_type, null) == "lambda" ? null : try(each.value.port, var.default_port)
  availability_zone = try(each.value.availability_zone, null)

  depends_on = [aws_lambda_permission.this]
}

This would also be backwards compatible, which is a plus. @bryantbiggs What do you think about this approach?

I don't want to get into the argument of things because I inherited this but what is the "solution" here ( I think they did this because VPCE private IPs were being load balanced and lambdas hung off of that) They even had things pinned to version 7.0.0. No ASGs or anything like that. It does work with 7.0.0, but that seems old.
  target_groups = [
    {
      name             = "lx-${local.application}-alb-tg-${local.env}-${local.region_short}"
      backend_protocol = "HTTPS"
      backend_port     = 443
      target_type      = "ip"
      vpc_id = data.aws_vpc.main.id
      health_check = {
        enabled             = true
        interval            = 10
        path                = "/"
        port                = "443"
        healthy_threshold   = 3
        unhealthy_threshold = 3
        timeout             = 5
        protocol            = "HTTPS"
        matcher             = "200,403"
      }
      targets = [
        {
          target_id = data.aws_network_interface.eni_ip_a.private_ip
          port      = 443
        },
        {
          target_id = data.aws_network_interface.eni_ip_b.private_ip
          port      = 443
        },
      ]
    }
  ]

@joshsizer yes I think we can add support for that (sorry, must have missed the last notification)

Awesome, I’ll work on a PR for this 👍

This issue has been resolved in version 9.7.0 :tada:

authors: an-stark antonbabenko bryantbiggs dbaber florianmagnin georambo iT3E joshsizer jseiser k911 pat-s rdhar remi-f-artelia stivi21

repo: terraform-aws-modules/terraform-aws-alb

license_source: bigquery


text:
listeners must have the same map

Description
It's not possible to use different listeners action directives, because the map must match. What can I do to bypass that situation?
The only apprach I can think is to replace this:
for_each = try([each.value.forward], [])

by this:
for_each = try(each.value.forward, null) != null ? [each.value.forward] : []

on all ocurrences (what I actually have done on my fork)
Versions

Module version [Required]: 9.1.0

Terraform version: v1.6.3

Provider version(s):

registry.terraform.io/hashicorp/aws v5.23.1

Reproduction Code [Required]

Steps to reproduce the behavior:
variables.tf
variable "load_balancers" {
  type = map(object({
    name                       = optional(string)
    create_security_group      = optional(bool, false)
    enable_deletion_protection = bool
    load_balancer_type         = string
    ip_address_type            = string
    preserve_host_header       = bool
    vpc_id                     = string
    subnets                    = set(string)
    security_groups            = set(string)
    target_groups = optional(map(object({
      arn    = string
      weight = optional(number)
    })), {})
    listeners = map(object({
      port            = number
      protocol        = string
      action_type     = string
      certificate_arn = optional(string)
      ssl_policy      = optional(string)
      redirect = optional(object({
        port        = number
        protocol    = string
        status_code = string
      }))
      fixed_response = optional(object({
        content_type = string
        message_body = string
        status_code  = number
      }))
    }))
    tags = optional(map(string))
  }))
}

prod.tfvars
load_balancers = {
  my-alb-prod = {
    enable_deletion_protection = true
    load_balancer_type         = "application"
    ip_address_type            = "dualstack"
    preserve_host_header       = true
    vpc_id                     = "<SENSITIVE_INFORMATION>"
    subnets = [<SENSITIVE_INFORMATION>]
    security_groups = [<SENSITIVE_INFORMATION>]
    listeners = {
      http = {
        port        = 80
        protocol    = "HTTP"
        action_type = "redirect"
        redirect = {
          port        = 443
          protocol    = "HTTPS"
          status_code = "HTTP_301"
        }
      },
      https = {
        port            = 443
        protocol        = "HTTPS"
        certificate_arn = "<SENSITIVE_INFORMATION>"
        ssl_policy      = "ELBSecurityPolicy-TLS-1-2-Ext-2018-06"
        action_type     = "fixed-response"
        fixed_response = {
          content_type = "text/plain"
          message_body = ""
          status_code  = 400
        }
      }
    }
    tags = {
      Name = "my-alb-prod"
    }
  }
}

main.tf
module "alb" {
  source = "terraform-aws-modules/alb/aws"
  for_each = var.load_balancers

  name                       = coalesce(each.value.name, each.key)
  create_security_group      = each.value.create_security_group
  enable_deletion_protection = each.value.enable_deletion_protection
  load_balancer_type         = each.value.load_balancer_type
  ip_address_type            = each.value.ip_address_type
  preserve_host_header       = each.value.preserve_host_header
  vpc_id                     = each.value.vpc_id
  subnets                    = each.value.subnets
  security_groups            = each.value.security_groups
  target_groups              = each.value.target_groups
  listeners                  = each.value.listeners
  tags                       = each.value.tags
}

Expected behavior

It should create two listeners, one HTTP, which only redirects to HTTPS, and one HTTPS, which have a default action of returning an empty string.
Actual behavior
I've tried two ways of doing this. First, my listeners variable was a map(any). However, I've received an error when running a plan
The given value is not suitable for var.load_balancers declared at
│ variables.tf:1,1-26: element "hole19-prod": attribute "listeners": all map
│ elements must have the same type.

After this I've created the fixed mapping you can see on variables.tf, but now the error is:
╷
│ Error: Attempt to get attribute from null value
│
│   on ../../modules/aws-networking-alb/main.tf line 124, in resource "aws_lb_listener" "this":
│  124:         content_type = default_action.value.content_type
│     ├────────────────
│     │ default_action.value is null
│
│ This value is null, so it does not have any attributes.
╵
╷
│ Error: Attempt to get attribute from null value
│
│   on ../../modules/aws-networking-alb/main.tf line 185, in resource "aws_lb_listener" "this":
│  185:         status_code = default_action.value.status_code
│     ├────────────────
│     │ default_action.value is null
│
│ This value is null, so it does not have any attributes.

Terminal Output Screenshot(s)

Additional context

thats because you've defined it this way
listeners = map(object({
      port            = number
      protocol        = string
      action_type     = string
      certificate_arn = optional(string)
      ssl_policy      = optional(string)
      redirect = optional(object({
        port        = number
        protocol    = string
        status_code = string
      }))
      fixed_response = optional(object({
        content_type = string
        message_body = string
        status_code  = number
      }))

Don't do that and the problem is resolved - this is why, unfortunately, we typically use any for complex types

You're right 😅, using any instead of map(any) solves the issue.


text:
After apply, it deleted my vpc

Describe the bug
Usedthe module to create an ALB. I used a previous module state as a data source. ALB gets created.
When it times out due to provisioning [no tgs currently], it eventually went and deleted my whole vpc!
Expected behavior
If the ALB times out, dont go delete the vpc
Desktop (please complete the following information):
MAC, TF 0.11.13, AWS-CLI 1.16.140
Additional context
I created a vpc using the official TF vpc module, but stripped the SG and Routes out for my own reasons.
I used the tfstate that was outputted to S3 for some vars for the ALB.
I manually entered the default SG.

Same result for logs or no logs
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

create

destroy

Terraform will perform the following actions:

module.alb.aws_lb.application_no_logs
id:
access_logs.#:
arn:
arn_suffix:
dns_name:
enable_deletion_protection: "true"
enable_http2:               "true"
idle_timeout:               "60"
internal:                   "false"
ip_address_type:            "ipv4"
load_balancer_type:         "application"
name:                       "web-alb-tmo-dev"
security_groups.#:          "1"
security_groups.3803735186: "sg-0b4f65678e77eefd3"
subnet_mapping.#:
subnets.#:                  "3"
subnets.1017906531:         "subnet-07110aaff57850aea"
subnets.3051565764:         "subnet-06c3a3f47b4464305"
subnets.3922050942:         "subnet-07e79bf57be2aceef"
tags.%:                     "5"
tags.Environment:           "test"
tags.GithubOrg:             "terraform-aws-modules"
tags.GithubRepo:            "tf-aws-alb"
tags.Name:                  "web-alb-tmo-dev"
tags.Workspace:             "default"
vpc_id:
zone_id:

module.vpc.aws_eip.nat[0]

module.vpc.aws_eip.nat[1]

module.vpc.aws_eip.nat[2]

module.vpc.aws_vpc.this

Did you create the ALB and VPC in the same state / module?
If you did, that's expected behaviour, and has nothing to do with this module, but rather on how Terraform and basic level works.

I honestly dont think so. Closing ticket - I was getting used to TF and have way more practise now - i had forgotten about this ticket it was so long ago.

authors: lsc omahonyb


text:
feat: Support the table class feature

Description
Support the table class feature.
Motivation and Context
AWS has introduced a new feature in dymanodb where you can select a table class for your table. If you create a new table with a specific table class, then this attribute would be specified. Therefore, using the current module if you need to provision a new table or import an existing table with that attribute set, that attribute would be set to NULL, which is prohibited.
This PR resolve the issue reported here: https://github.com/terraform-aws-modules/terraform-aws-dynamodb-table/issues/52
Breaking Changes
This change does not break anything.
How Has This Been Tested?

[x] I have updated at least one of the examples/* to demonstrate and validate my change(s)
[X] I have tested and validated these changes using one or more of the provided examples/* projects
A table with that attribute was created to make sure all is fine. All went well.

This issue has been resolved in version 1.3.0 :tada:

Thank you for this PR, I have finished it in #54 (due to a lack of write access to your fork)

authors: antonbabenko haytham-salhi


text:
fix: Make guards in case aws_eks_cluster.this is empty

PR o'clock
Description
Fix syntax in data elements pulling when a the cluster element is being imported.
In the case of an aws token expiring while the cluster is created, the state might be left without the eks cluster. Upon running an import command for the cluster, the refresh step of the import fails as the cluster does not exist yet. This PR adds some data guards so that this step succeeds without errors:
$ terraform import module.terraform-aws-modules.aws_eks_cluster.this[0] my-cluster

module.terraform-aws-modules.aws_eks_cluster.this[0]: Importing from ID "my-cluster"...
module.terraform-aws-modules.aws_eks_cluster.this[0]: Import prepared!
  Prepared aws_eks_cluster for import
module.terraform-aws-modules.aws_eks_cluster.this[0]: Refreshing state... [id=my-cluster]

Error: Invalid index
  on .terraform/modules/terraform-aws-modules/local.tf line 147, in locals:
 147:     endpoint                          = aws_eks_cluster.this[0].endpoint
    |----------------
    | aws_eks_cluster.this is empty tuple

The given key does not identify an element in this collection value.

Error: Invalid index

  on .terraform/modules/terraform-aws-modules/local.tf line 148, in locals:
 148:     cluster_auth_base64               = aws_eks_cluster.this[0].certificate_authority[0].data
    |----------------
    | aws_eks_cluster.this is empty tuple

The given key does not identify an element in this collection value.

Error: Invalid index

  on .terraform/modules/terraform-aws-modules/local.tf line 150, in locals:
 150:     aws_authenticator_command_args    = length(var.kubeconfig_aws_authenticator_command_args) > 0 ? var.kubeconfig_aws_authent
icator_command_args : ["token", "-i", aws_eks_cluster.this[0].name]
    |----------------
    | aws_eks_cluster.this is empty tuple

The given key does not identify an element in this collection value.

with the PR:
Acquiring state lock. This may take a few moments...
module.terraform-aws-modules.aws_eks_cluster.this[0]: Importing from ID "my-cluster"...
module.terraform-aws-modules.aws_eks_cluster.this[0]: Import prepared!
  Prepared aws_eks_cluster for import
module.terraform-aws-modules.aws_eks_cluster.this[0]: Refreshing state... [id=my-cluster]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Checklist

[ ] CI tests are passing
[ ] README.md has been updated after any changes to variables and outputs. See https://github.com/terraform-aws-modules/terraform-aws-eks/#doc-generation

There is already an on going PR which address this https://github.com/terraform-aws-modules/terraform-aws-eks/pull/1040
My comments about splat syntax still apply here.

Thanks @Carles-Figuerola  for your work. I'm closing this in favor of https://github.com/terraform-aws-modules/terraform-aws-eks/pull/1041

authors: Carles-Figuerola barryib

repo: terraform-aws-modules/terraform-aws-eks


text:
terraform-aws-memory-db: include lifecycle block to aws_memorydb_cluster to avoid possible downtimes

Is your request related to a new offering from AWS?
Is this functionality available in the AWS provider for Terraform? See CHANGELOG.md, too.

No 🛑: please wait to file a request until the functionality is avaialble in the AWS provider
Yes ✅: please list the AWS provider version which introduced this functionality

Is your request related to a problem? Please describe.
I am using the terraform-aws-modules/terraform-aws-memory-db module but I am seeing creating and destroying of the aws_memorydb_cluster, simultaneously. This might cause an abrupt breaking change for an application that relies on the MemoryDB cluster and could lead to app crashes, possibly longer downtimes.
Describe the solution you'd like.
It would be great if had a lifecycle block (as shown below) on the aws_memorydb_cluster resource as well so we can reduce the amount of downtime for the application. We would still need to pass the newer cluster_endpoint_address downstream to dependent compute resources, like Lambda, EC2 and so on.
lifecycle {
  create_before_destroy = true
}

The proposed change could reduce the amount of time for the application to come back online.
Describe alternatives you've considered.
I would love to throw a lifecycle block on the module reference code in Terraform but lifecycle is not supported on modules yet. Refer https://github.com/hashicorp/terraform/issues/27360.
I am willing to fork the repository and make the changes and submit a PR, if the changes/feature request makes sense.
Thank you for your contributions to the Terraform community!
Additional context

@bryantbiggs Do you think this feature request would be helpful for module users? I would love to hear your comments. Thank you.

I'm trying to understand how this will avoid downtime? If the end result is always the deletion and re-creation of a DB, that still means downtime and data loss

Sorry for the delayed response. Having a replacement DB created before we destroy the existing DB in use would only require switching connection strings on the application end (say Lambda functions) and can be modified using Terraform. This would reduce the amount of downtime for the application as the Memory DB replacement slides in.

closing this for now unless there is further evidence that this is solving an issue

authors: GeorgeDavis-TriumphTech bryantbiggs


text:
Exclude resources

New tag to exclude resources from tagged scenario.
Usage:
@exclude_aws_s3_bucket.mybucket or @ignore_resource_type.resource_name
Addresses #384

The above doesn't seem to work on Scenario Outline
When it assesses the child module inside the child module it fails. When it assess the resource, it passes the tests.
Terraform version: Terraform v0.13.3
Terraform-compliance vesrion terraform-compliance v1.3.9 (reproducible on 1.3.6 too)
module.example.module.aws_lambda_function.aws_lambda_function.this will be created

resource "aws_lambda_function" "this" {

arn                            = (known after apply)

description                    = "Example lambda function"

filename                       = ".terraform/modules/example.aws_lambda_function/function/.terraform/archive_files/lambda_placeholder_content.zip"

function_name                  = "nonprod-uk-pc2-pipelines-example"

handler                        = "main.handler"

id                             = (known after apply)

invoke_arn                     = (known after apply)

last_modified                  = (known after apply)

memory_size                    = 128

package_type                   = "Zip"

publish                        = false

qualified_arn                  = (known after apply)

reserved_concurrent_executions = -1

role                           = (known after apply)

runtime                        = "python3.7"

signing_job_arn                = (known after apply)

signing_profile_version_arn    = (known after apply)

source_code_hash               = "blah"

source_code_size               = (known after apply)

tags                           = {

"Account"     = "nonprod"
"Component"   = "aws-lambda"
"Environment" = "pc2-pipelines"
"Handle"      = ""
"Location"    = "uk"
"Name"        = "nonprod-uk-pc2-pipelines-example"
"Service"     = "example"
"Squad"       = "blah"
"Tribe"       = "blah"
}

timeout                        = 3

version                        = (known after apply)

tracing_config {

mode = "Active"
}
}
Scenario:

Scenario Outline: Ensure that specific tags are defined
Given I have resource that supports tags defined
When it has tags
Then it must contain <tag_keys>
And its value must match the "<tag_value>" regex
Examples:
| tag_keys          | tag_value                                                                                |
| Name              | .+                                                                                |
| Environment       | ^(playground|sandbox|dev|staging|preprod|prod|pc2-pipelines|pc2-service-pipelines)$      |
| Component         | .+                                                                                |
| Service           | .+                                                                                |
| Location          | ^(uk|global1|sg|us|ca)$
Failure:

Scenario Outline: Ensure that specific tags are defined
Given I have resource that supports tags defined
When it has tags
Then it must contain <tag_keys>
And its value must match the "<tag_value>" regex
Examples:
    | tag_keys    | tag_value                                                                           |
    | Name        | .+                                                                                |
            Failure: module.example.module.aws_lambda_function.aws_lambda_function.this (aws_lambda_function) does not have Environment property.
    | Environment | ^(playground|sandbox|dev|staging|preprod|prod|pc2-pipelines|pc2-service-pipelines)$ |
      Failure:
    | Component   | .+                                                                                |

    | Service     | .+                                                                                |
    | Location    | ^(uk|global1|sg|us|ca)$     |

Even by adding the exclude tag, it still fails for this resource. So far the only workaround I found is to skip the whole scenario but that isn't ideal

The above doesn't seem to work on Scenario Outline
When it assesses the child module inside the child module it fails. When it assess the resource, it passes the tests.
Terraform version: Terraform v0.13.3
Terraform-compliance vesrion terraform-compliance v1.3.9 (reproducible on 1.3.6 too)
module.example.module.aws_lambda_function.aws_lambda_function.this will be created

resource "aws_lambda_function" "this" {

arn                            = (known after apply)

description                    = "Example lambda function"

filename                       = ".terraform/modules/example.aws_lambda_function/function/.terraform/archive_files/lambda_placeholder_content.zip"

function_name                  = "nonprod-uk-pc2-pipelines-example"

handler                        = "main.handler"

id                             = (known after apply)

invoke_arn                     = (known after apply)

last_modified                  = (known after apply)

memory_size                    = 128

package_type                   = "Zip"

publish                        = false

qualified_arn                  = (known after apply)

reserved_concurrent_executions = -1

role                           = (known after apply)

runtime                        = "python3.7"

signing_job_arn                = (known after apply)

signing_profile_version_arn    = (known after apply)

source_code_hash               = "blah"

source_code_size               = (known after apply)

tags                           = {

"Account"     = "nonprod"
"Component"   = "aws-lambda"
"Environment" = "pc2-pipelines"
"Handle"      = ""
"Location"    = "uk"
"Name"        = "nonprod-uk-pc2-pipelines-example"
"Service"     = "example"
"Squad"       = "blah"
"Tribe"       = "blah"
}

timeout                        = 3

version                        = (known after apply)

tracing_config {

mode = "Active"
}
}
Scenario:

Scenario Outline: Ensure that specific tags are defined
Given I have resource that supports tags defined
When it has tags
Then it must contain <tag_keys>
And its value must match the "<tag_value>" regex
Examples:
| tag_keys          | tag_value                                                                                |
| Name              | .+                                                                                |
| Environment       | ^(playground|sandbox|dev|staging|preprod|prod|pc2-pipelines|pc2-service-pipelines)$      |
| Component         | .+                                                                                |
| Service           | .+                                                                                |
| Location          | ^(uk|global1|sg|us|ca)$
Failure:

Scenario Outline: Ensure that specific tags are defined
Given I have resource that supports tags defined
When it has tags
Then it must contain <tag_keys>
And its value must match the "<tag_value>" regex
Examples:
    | tag_keys    | tag_value                                                                           |
    | Name        | .+                                                                                |
            Failure: module.example.module.aws_lambda_function.aws_lambda_function.this (aws_lambda_function) does not have Environment property.
    | Environment | ^(playground|sandbox|dev|staging|preprod|prod|pc2-pipelines|pc2-service-pipelines)$ |
      Failure:
    | Component   | .+                                                                                |

    | Service     | .+                                                                                |
    | Location    | ^(uk|global1|sg|us|ca)$     |

Even by adding the exclude tag, it still fails for this resource. So far the only workaround I found is to skip the whole scenario but that isn't ideal

Hi @hpapadopoulos
Thanks for reporting this issue. I suspect the problem you are facing could be more about using modules and less about using scenario outlines. I'm making some changes on how this tag works.
Does #448 fix your problem? If not, could you convert this report to an issue so that it doesn't get lost.
If you happened to open an issue, could you also share an anonymized plan. It makes reproducing your problem easier :)

Hi @hpapadopoulos
Thanks for reporting this issue. I suspect the problem you are facing could be more about using modules and less about using scenario outlines. I'm making some changes on how this tag works.
Does #448 fix your problem? If not, could you convert this report to an issue so that it doesn't get lost.
If you happened to open an issue, could you also share an anonymized plan. It makes reproducing your problem easier :)

Hi @Kudbettin , apologies for the huge delay in coming back to you. Yup, looks like that PR works ok.
Thank you for looking into that

authors: Kudbettin hpapadopoulos

repo: terraform-compliance/cli


text:
chore(deps): update common-dev-assets digest to 1d3b343

This PR contains the following updates:

Package
Update
Change

common-dev-assets
digest
23a510d -> 1d3b343

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

/run pipeline

/run pipeline

/run pipeline

/run pipeline

:tada: This PR is included in version 3.25.5 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
Terraform doc for submodule is not generated

Example: https://github.com/terraform-ibm-modules/terraform-ibm-cbr/tree/main/profiles/fscloud - the terra doc in this markdown file is not longer generated.
Note:
 is used in this version in order to force generation using terraform-doc command line. This is a workaround for the issue, rather than the cause.

Hello @ocofaigh - is this a known issue?

@vburckhardt Recently we migrated from the official terradocs pre-commit hook to our own custom extended version. It looks like the custom script is only set up to apply on the main readme, which is a bug. Andrej is out, but I should be able to fix it

I also noticed that the metadata tags being used in the submodule readme is incorrect. It has <!-- BEGIN_TF_DOCS --> when it should be <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->, so this never would of worked in this module.
I will create a PR to fix once I update the custom hook.

Fix is in https://github.com/terraform-ibm-modules/common-dev-assets/pull/703

PR to fix the CBR module docs https://github.com/terraform-ibm-modules/terraform-ibm-cbr/pull/272

Seems to be a bug in the fix, so I have reverted it while I debug

authors: ocofaigh vburckhardt

repo: terraform-ibm-modules/terraform-ibm-cbr


text:
chore(deps): update ci dependencies

This PR contains the following updates:

Package
Type
Update
Change

common-dev-assets

digest
0a4ea52 -> eb1c66a

github.com/IBM/go-sdk-core/v5
require
patch
v5.17.0 -> v5.17.2

go (source)
toolchain
patch
1.22.2 -> 1.22.3

Release Notes

IBM/go-sdk-core (github.com/IBM/go-sdk-core/v5)
v5.17.2
Compare Source
Bug Fixes

errors: flatten sdk problem chains to reduce hash complexity (#218) (9fc1ebc)

v5.17.1
Compare Source
Bug Fixes

use correct error variable in external auth case (#217) (0b70d7d)

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

/run pipeline

:tada: This PR is included in version 1.22.1 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
chore(deps): update ci dependencies

This PR contains the following updates:

Package
Type
Update
Change

common-dev-assets

digest
58d733c -> 15d26df

github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper
require
minor
v1.23.16 -> v1.24.1

Release Notes

terraform-ibm-modules/ibmcloud-terratest-wrapper (github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper)
v1.24.1
Compare Source
Bug Fixes

deps: update gomod (#699) (3c7a2b2)

v1.24.0
Compare Source
Features

add containers for getting iks config (#698) (c8cdb82)

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

/run pipeline

/run pipeline

/run pipeline

:tada: This PR is included in version 1.0.2 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
Update doc on HPCS encryption keys for backups

Description

Update doc on HPCS encryption keys for backups
GE Issue - https://github.ibm.com/GoldenEye/issues/issues/9359
Release required?

[ ] No release
[ ] Patch release (x.x.X)
[ ] Minor release (x.X.x)
[ ] Major release (X.x.x)

Release notes content

Run the pipeline
If the CI pipeline doesn't run when you create the PR, the PR requires a user with GitHub collaborators access to run the pipeline.
Run the CI pipeline when the PR is ready for review and you expect tests to pass. Add a comment to the PR with the following text:
/run pipeline

Checklist for reviewers

[ ] If relevant, a test for the change is included or updated with this PR.
[ ] If relevant, documentation for the change is included or updated with this PR.

For mergers

Use a conventional commit message to set the release level. Follow the guidelines.
Include information that users need to know about the PR in the commit message. The commit message becomes part of the GitHub release notes.
Use the Squash and merge option.

/run pipeline

/run pipeline

/run pipeline

Changes in this PR has been taken care: https://github.com/terraform-ibm-modules/terraform-ibm-icd-elasticsearch/pull/210


text:
chore(deps): update terraform terraform-ibm-modules/kms-all-inclusive/ibm to v4.15.10

This PR contains the following updates:

Package
Type
Update
Change

terraform-ibm-modules/kms-all-inclusive/ibm (source)
module
patch
4.15.9 -> 4.15.10

Release Notes

terraform-ibm-modules/terraform-ibm-kms-all-inclusive (terraform-ibm-modules/kms-all-inclusive/ibm)
v4.15.10
Compare Source
Bug Fixes

deps: update terraform ibm to latest for the deployable architecture solution (#543) (fb3c57c)

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

:tada: This PR is included in version 1.10.9 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
fix: Fix output error for hostname and port

Description
When using this module we get this error:
 2023/08/11 07:34:22 Terraform apply |
 2023/08/11 07:34:22 Terraform apply | Error: Error in function call
 2023/08/11 07:34:22 Terraform apply |
 2023/08/11 07:34:22 Terraform apply |   on .terraform/modules/icd_postgresql/outputs.tf line 44, in output "hostname":
 2023/08/11 07:34:22 Terraform apply |   44:   value       = length(var.service_credential_names) > 0 ? nonsensitive(ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.hosts.0.hostname"]) : length(var.users) > 0 ? nonsensitive(flatten(data.ibm_database_connection.database_connection[0].postgres[0].hosts[0].hostname)) : null
 2023/08/11 07:34:22 Terraform apply |     ├────────────────
 2023/08/11 07:34:22 Terraform apply |     │ while calling flatten(list)
 2023/08/11 07:34:22 Terraform apply |     │ data.ibm_database_connection.database_connection[0].postgres[0].hosts[0].hostname is "215daa49-149e-497c-9985-171ad7234915.497129fd685f442ca4df759dd55ec01b.databases.appdomain.cloud"
 2023/08/11 07:34:22 Terraform apply |
 2023/08/11 07:34:22 Terraform apply | Call to function "flatten" failed: can only flatten lists, sets and tuples.
 2023/08/11 07:34:22 Terraform apply |
 2023/08/11 07:34:22 Terraform apply | Error: Error in function call
 2023/08/11 07:34:22 Terraform apply |
 2023/08/11 07:34:22 Terraform apply |   on .terraform/modules/icd_postgresql/outputs.tf line 49, in output "port":
 2023/08/11 07:34:22 Terraform apply |   49:   value       = length(var.service_credential_names) > 0 ? nonsensitive(ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.hosts.0.port"]) : length(var.users) > 0 ? nonsensitive(flatten(data.ibm_database_connection.database_connection[0].postgres[0].hosts[0].port)) : null
 2023/08/11 07:34:22 Terraform apply |     ├────────────────
 2023/08/11 07:34:22 Terraform apply |     │ while calling flatten(list)
 2023/08/11 07:34:22 Terraform apply |     │ data.ibm_database_connection.database_connection[0].postgres[0].hosts[0].port is 30965
 2023/08/11 07:34:22 Terraform apply |
 2023/08/11 07:34:22 Terraform apply | Call to function "flatten" failed: can only flatten lists, sets and tuples.

The terraform provider documentation states that the hostname and port are strings and those can't be flattened. Therefore this PR removes this part.
Release required?
Identify the type of release. For information about the changes in a semantic versioning release, see Release versioning.

[ ] No release
[x] Patch release (x.x.X)
[ ] Minor release (x.X.x)
[ ] Major release (X.x.x)

Release notes content
If a release is required, replace this text with information that users need to know about the release. Write the release notes to help users understand the changes, and include information about how to update from the previous version.
Your notes help the merger write the commit message for the PR that is published in the release notes for the module.
Run the pipeline
If the CI pipeline doesn't run when you create the PR, the PR requires a user with GitHub collaborators access to run the pipeline.
Run the CI pipeline when the PR is ready for review and you expect tests to pass. Add a comment to the PR with the following text:
/run pipeline

Checklist for reviewers

[ ] If relevant, a test for the change is included or updated with this PR.
[ ] If relevant, documentation for the change is included or updated with this PR.

Merge actions for mergers

Use a relevant conventional commit message that is based on the PR contents and any release notes provided by the PR author. The commit message determines whether a new version of the module is needed, and if so, which semver increment to use (major, minor, or patch).
Merge by using "Squash and merge".

/run pipeline

:tada: This PR is included in version 3.4.5 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
chore(deps): update common-dev-assets digest to fafc30b

This PR contains the following updates:

Package
Update
Change

common-dev-assets
digest
038ee9e -> fafc30b

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline


text:
chore(deps): update common-dev-assets digest to dda6d1f

This PR contains the following updates:

Package
Update
Change

common-dev-assets
digest
96f7642 -> dda6d1f

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

:tada: This PR is included in version 2.3.2 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
chore(deps): update common-dev-assets digest to ab267b7

This PR contains the following updates:

Package
Update
Change

common-dev-assets
digest
84f003e -> ab267b7

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

:tada: This PR is included in version 2.3.2 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
chore(deps): update module github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper to v1.8.10

This PR contains the following updates:

Package
Type
Update
Change

github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper
require
patch
v1.8.9 -> v1.8.10

Release Notes

terraform-ibm-modules/ibmcloud-terratest-wrapper
v1.8.10
Compare Source
Bug Fixes

deps: update gomod (#534) (e9bace0)

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

Edited/Blocked Notification
Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.
You can manually request rebase by checking the rebase/retry box above.
⚠ Warning: custom changes will be lost.

:tada: This PR is included in version 7.1.0 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
chore(deps): update module github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper to v1.2.11

This PR contains the following updates:

Package
Type
Update
Change

github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper
require
patch
v1.2.10 -> v1.2.11

Release Notes

terraform-ibm-modules/ibmcloud-terratest-wrapper
v1.2.11
Compare Source
Bug Fixes

deps: update module github.com/ibm/platform-services-go-sdk to v0.31.0 (#201) (a1c8717)

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, click this checkbox.

This PR has been generated by Renovate Bot.

@surajsbharadwaj can you check to see why these tests are failing?

:tada: This PR is included in version 5.2.1 :tada:
The release is available on:

GitHub release
v5.2.1

Your semantic-release bot :package::rocket:

authors: ocofaigh terraform-ibm-modules-ops


text:
fix: fixed bug in validation when passing existing SM instance

Description
Fix for https://github.com/terraform-ibm-modules/terraform-ibm-secrets-manager/issues/172
Release required?

[ ] No release
[ ] Patch release (x.x.X)
[ ] Minor release (x.X.x)
[ ] Major release (X.x.x)

Release notes content

Run the pipeline
If the CI pipeline doesn't run when you create the PR, the PR requires a user with GitHub collaborators access to run the pipeline.
Run the CI pipeline when the PR is ready for review and you expect tests to pass. Add a comment to the PR with the following text:
/run pipeline

Checklist for reviewers

[ ] If relevant, a test for the change is included or updated with this PR.
[ ] If relevant, documentation for the change is included or updated with this PR.

For mergers

Use a conventional commit message to set the release level. Follow the guidelines.
Include information that users need to know about the PR in the commit message. The commit message becomes part of the GitHub release notes.
Use the Squash and merge option.

/run pipeline

/run pipeline

:tada: This issue has been resolved in version 1.17.1 :tada:
The release is available on:

GitHub release
v1.17.1

Your semantic-release bot :package::rocket:


text:
fix(deps): update icr.io/cpopen/ibm-licensing-catalog docker digest to b912aab

This PR contains the following updates:

Package
Update
Change

icr.io/cpopen/ibm-licensing-catalog
digest
1bc20fa -> b912aab

Configuration
📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.

[ ] If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

/run pipeline

:tada: This PR is included in version 1.0.1 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


text:
test: update to latest postresql module version

Description
Update the default example to latest postgresql module version that contains provider fix.
Due to a deprecation of certain ICD parameters in the IBM provider, the older versions of these examples will fail always. Skipping this upgrade test as it is expected to fail.
Release required?

[x] No release
[ ] Patch release (x.x.X)
[ ] Minor release (x.X.x)
[ ] Major release (X.x.x)

Release notes content

Run the pipeline
If the CI pipeline doesn't run when you create the PR, the PR requires a user with GitHub collaborators access to run the pipeline.
Run the CI pipeline when the PR is ready for review and you expect tests to pass. Add a comment to the PR with the following text:
/run pipeline

Checklist for reviewers

[ ] If relevant, a test for the change is included or updated with this PR.
[ ] If relevant, documentation for the change is included or updated with this PR.

For mergers

Use a conventional commit message to set the release level. Follow the guidelines.
Include information that users need to know about the PR in the commit message. The commit message becomes part of the GitHub release notes.
Use the Squash and merge option.

/run pipeline

:tada: This PR is included in version 3.2.0 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:

authors: terraform-ibm-modules-ops toddgiguere


text:
Adding impl and test tags for requirements

What is the change?
This PR adds a smattering of impl and test tags for requirements in:

interfaces
materials
plugins
globalFluxInterface

Why is the change being made?
This is part of the on-going work on ARMI requirements.

Checklist

[X] This PR has only one purpose or idea.
[X] Tests have been added/updated to verify that the new/changed code works.

[X] The code style follows good practices.
[X] The commit message(s) follow good practices.

[X] The release notes (location doc/release/0.X.rst) are up-to-date with any important changes.
[X] The documentation is still up-to-date in the doc folder.
[X] No requirements were altered.
[X] The dependencies are still up-to-date in pyproject.toml.

@bdlafleur Just FYI.

repo: terrapower/armi


text:
Hyperspectral solstice calibration diurnal scan

@dlebauer and @czender @solmazhajmohammadi - please update and assign to Stuart
Fixed x and y location of target preferred to reduce man hours of finding targets; best to run in same mode  every time (trigger mode v. free-running).  However, VNIR isn't working in trigger mode right now so this may not be possible.

One reason to re-calibrate is to potentially avoid the need to manually identify the target location, which currently drifts with the 20170415 images as shown in #281. If that issue cannot be eliminated , then a new calibration will require just as much work as the 20170415 calibration. Aother reason to recalibrate is to obtain imagery at peak solar zenith angles (~10 degrees) that are reached near solstice.

@smarshall-bmr please update the script that you are running, comment out the delays for dark measurement in SWIR camera. and disable the dark measurement in SWIR (this should be done in a separate night scan). This would make it easier to georeference the datacube.

@smarshall-bmr any updates on this? Have you been able to run another calibration?

Rerun on 8/9 with these targets: 75, 25, 99, 2 color, ceramic tile

@hmb1 please check data and close issue

@hmb1 will you be able to use scans where targets are in 1/2 shade, 1/2 sun?

The scan has been completed; this issue can be closed.

For 8/9 the calibration images are every 5th scan

authors: czender dlebauer rachelshekar solmazhajmohammadi

repo: terraref/computing-pipeline


text:
Added Vehicle Speed and Location to the Overview page

Shows the vehicle speed based on the last speed from their position data point
Shows the vehicle's last known position from the position data point

First PR into this project. Let me know if there are PR requirements somewhere, I couldn't find it.

Going to close as I don't feel that this fits the overview dashboard. The overview dashboard has a lot of data over time, so it would be confusing to users to say MPH. MPH when? Also stale and needs to be rebased,

authors: Dulanic ddshd

repo: teslamate-org/teslamate


text:
t2 run/push: insert os or firmware version request into pipeline

Presently we have access to process.versions, I just want to confirm that it includes the information that we need to determine the appropriate SDK marker for pre-compiled module requests

https://github.com/tessel/t2-cli/commit/208842091d8f80ddfe6910507e3349df43389a55

license: mit


text:
Co-ordinates received by GetWordStrBoxText sequence does not match with WordStr start and end co-ordinates.

Co-ordinates received by GetWordStrBoxText sequence does not match with WordStr start and end co-ordinates. As moved from top to bottom Y co-ordinate decreases but in single WordStr start point Y is smaller than end point Y.
Example:
WordStr 1922 2871 2196 2893 0 # ...
2197 2871 2201 2893 0
WordStr 177 2828 568 2854 0 # ...
569 2828 573 2854 0
WordStr 1474 2827 1719 2855 0 # ...
1720 2827 1724 2855 0
WordStr 1921 2834 2231 2856 0 # ...
2232 2834 2236 2856 0

You should post an image and the commands you used to produce the two different output. Also add the output of tesseract -v command.

Its my mistake.

It seems the two co-ordinates received from the string box is from lower left and upper top.

authors: PratapMehra amitdo

repo: tesseract-ocr/tesseract


text:
Revamp API

As of now, we support a rather ambiguous interface, e.g.
@suite.only('name')
class foo {

  @test.only('name')
  test() {}

  @test('name')
  @only
  test2() {}
}

I would like to simplify the decorators by eliminating
interface SuiteDecorator {
   only(...); /* removed */
   skip(...); /* removed */
   pending(...); /* removed */
}

interface TestDecorator {
   only(...); /* removed */
   skip(...); /* removed */
   pending(...); /* removed */
}

requiring the user to then use the decorators only, e.g.
@suite
@skip
class foo {
}

Similarly so for timeout, retries, and slow, e.g.
@test(slow(100))
test() {}

becomes
@test
@slow(100)
test() {}

IMHO this will make things easier to both author and read. Not to mention that we can then simplify our code.
In addition to that I would like to move the naming option to a separate decorator, e.g.
@suite('foo')
class Suite {

  @test('bar')
  foo() {}
}

becomes
@suite
@name('foo')
class Suite {

  @test
  @name('bar')
  foo() {}
}

Again, this will make things much easier to author, e.g. just outcomment the name decorator or remove it using simple editor commands.
AFAIK we also have a naming decorator for the test parameters...
So we could also combine these two, making it a single decorator.

@pana-cc Not to mention #312 where I have a hard time to make things work 😄 according to some rather simplistic standard typescript-eslint rules.

I’ve been thinking about cutting all non-essentials too, but my line of thought was going the other way around - instead of providing each property as a separate decorator to just stick with a single decorator and an optional options object. That would mean to delete using just ’@test’, all ’test.*’, the ‘@timeout’ and ‘@slow’ as well and support only:
’’’
function test(options: {
name?: string,
only?: boolean,
skip?: boolean,
timeout?: number,
slow?: number,
retries?: number
} = {}): MethodDecorator {
//…
}
’’’
Similar for ‘@suite’.
:(
But I also really love how simple this looks:
’’’ typescript
@suite class MyClass {
@test myTest() {
}
}
’’’
Another thing I’ve been considering is drop the support for ‘done’ callbacks and stick to promises for async tests. It will avoid all the if-y function wrapping that is trying to create a method execution function with a single ‘done’ arg matching the method signature.
We could probably fork the project, or add a testdeck2 (given we consider the current 0.*-ish a v1) with a radically minimised API. We can also delete all the ifs checking for Symbols, symbols are everywhere.

This is as far as I get with my typings magic.
// This requires tsconfig like:
// {
//     "compilerOptions": {
//         "experimentalDecorators": true,
//         "target": "ES2022"
//     }
// }

interface TestOptions {
    name?: string;
    timeout?: number;
    slow?: number;
}

// Remove the `| (() => Promise<P[]>)` from here...
type ParamsTestOptions<ParamsType> = { params: ParamsType[] | (() => Promise<ParamsType[]>) } & TestOptions;

function isParamsOptions<ParamsType>(options: TestOptions | ParamsTestOptions<ParamsType>): options is ParamsTestOptions<ParamsType> {
    return "params" in options;
}

// I woundn't mind deleting support for "done" callback
type DoneCallback = (err?) => void;

type SyncTest = (() => void)
type CallbackAsyncTest = (done: DoneCallback) => void;
type PromiseAsyncTest = (() => Promise<void>);
type TestMethodSignature = SyncTest | CallbackAsyncTest | PromiseAsyncTest;

type ParamsSyncTest<ParamsType> = ((args: ParamsType) => void);
type ParamsCallbackAsyncTest<ParamsType> = ((args: ParamsType, done: DoneCallback) => void);
type ParamsPromiseAsyncTest<ParamsType> = ((args: ParamsType) => Promise<void>);
type ParamsTestMethodSignature<ParamsType> = ParamsSyncTest<ParamsType> | ParamsCallbackAsyncTest<ParamsType> | ParamsPromiseAsyncTest<ParamsType>;

export const testsSymbol: unique symbol = Symbol("tests");
interface Prototype extends Object {
    [testsSymbol]?: {
        [key: string | symbol]: TestOptions
    }
}

// Probably add beforeMethodsSymbol and afterMethodsSymbol

type TypedMethodDecorator<T> = (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => void;
function test(options?: TestOptions): TypedMethodDecorator<TestMethodSignature>
function test<ParamsType>(options: ParamsTestOptions<ParamsType>): TypedMethodDecorator<ParamsTestMethodSignature<ParamsType>>
function test<ParamsType>(options?: TestOptions | ParamsTestOptions<ParamsType>): TypedMethodDecorator<TestMethodSignature> | TypedMethodDecorator<ParamsTestMethodSignature<ParamsType>> {
    return (target: Prototype, propertyKey: string | symbol) => {
        // Here you should pretty much attach the options (and params) metadata on the class somehow, because the "suite" decorator
        // executes after all test decorators

        // We used to do something like: target[propertyKey][testSymbol] = { options, params }
        // but that was attaching the metadata on the method function and wouldnt allow polymorphism (using a @test on base class to run tests in each derived class marked with @suite)
        // and also if other mutating decorators were used they would swap the method function and we couldn't get our metadata when executing @suite

        // Something like this, but if we support inheritance it may need to be a kind of Object.hasOwnProperty(target, testSymbol)... because the base class may already contain a test method with the same name... in @suite we can inspect the inheritance chain and allow options in derived classes to override options in base classes etc.
        if (!target[testsSymbol]) target[testsSymbol] = {};
        const classTests = target[testsSymbol];
        classTests[propertyKey] = options;

        if (isParamsOptions(options)) {
            // This will declare multiple tests when the @suite() decorator executes
        } else {
            // This will declare a single test
        }
    };
}

declare function describe(name: string, s: () => void);
declare function it(name: string, t: () => void);

// and then in @suite something along
function suite(): ClassDecorator {
    return <TFunction extends Function>(target: TFunction) => {

        // Here use the abstracted testdeck API instead of describe/it directly?
        // Or if the code is cure enough, we can just support multiple implementations in parallel,
        // without reusable code between the different test runners...

        describe("...", () => {
            const classTests = (target.prototype as Prototype)[testsSymbol];
            for(const propertyKey in classTests) {
                const options = classTests[propertyKey];
                // test may be a symbol here... maybe use ?.toString()
                it(options.name ?? propertyKey, () => {
                });
            }
        });
    }
}

// Attmpt 2
function test2(options?: TestOptions): TypedMethodDecorator<TestMethodSignature>
function test2<ParamsType>(options: TestOptions, ... params: ParamsType[]): TypedMethodDecorator<ParamsTestMethodSignature<ParamsType>>
function test2<ParamsType>(options?: TestOptions, ... params: ParamsType[]): TypedMethodDecorator<TestMethodSignature> | TypedMethodDecorator<ParamsTestMethodSignature<ParamsType>> {
    return (target: Object, propertyKey: string | symbol) => {
        // Here you should pretty much attach the options (and params) metadata on the class somehow, because the "suite" decorator
        // executes after all test decorators

        if (params && params.length > 0) {
            // This will declare multiple tests when the @suite() decorator executes
        } else {
            // This will declare a single test
        }
    };
}

interface Point {
    x: number;
    y: number;
}

class X {
    @test({
        name: "Hello World!"
    })
    myTest() {
    }

    @test()
    myCallbackAsyncTest(done: DoneCallback) {
        done(new Error("Fail fast!"));
    }

    @test({
        name: "Fancy name"
    })
    myFancyNameTest() {
    }

    @test({
        params: [
            { x: 10, y: 20 },
            { x: 22, y: 33 },
        ]
    })
    myParamsTest1({ x, y }: { x: number, y: number }) {
    }

    @test({
        params: [
            { x: 10, /* If you hit ctrl + space here, you get no suggestions :( */y: 30 },
            { x: 10, /* If you hit ctrl + space here, you get y? suggested because of the previous array item has property Y */ }
            // You get no errors for missing "y" property
        ]
    })
    myParamsTest2({ x, y }: { x: number, y: number }, done: DoneCallback) {
    }

    // This will generate a nice error! Somewhere along the lines containing: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'.
    @test({
        params: [
            { x: 10, y: "myproperty" },
        ]
    })
    myParamsTest3({ x, y }: { x: number, y: number }) {
    }

    // This will generate an error, somewhere along the lines containing: Type '{ x: number; y: string; }' is not assignable to type '{ x: number; y: number; }'.
    @test({
        params: [
            { x: 10, y: "myproperty" }
        ]
    })
    myParamsTest4({ x, y }) {
        // x and y here are any :( need to provide a type in the signature
    }

    @test({
        // Not sure if this is at all possible with the test frameworks... probably not, but I wish it was... It could asynchronously load CSV files and declare tests if
        // the "suite" function could be async... Like in a `describe("suite", async () => { for await(const line of loadCSVAsync()) { it("test line" + line, () => { test(line) })} })`
        async params() {
            return [
                { x: 10, y: 30}
            ]
        }
    })
    async myParamsTest5({ x, y }) {
        // x and y here are any :( need to provide a type in the signature
    }

    @test<Point>({
        params: [
            { x: 10, y: 20},
            // You again get zero help here...
        ]
    })
    async myPramsTest6({x, y}: Point) {
    }

    @test2({
        name: "MyFancyName"
    })
    async myTest2() {
    }

    @test2<Point>({},
        { x: 10, y: 20 },
        { x: 10, }, // <- You get a nice "Property y is missing... error"
        { x: 20, y: "asd" })  // <- You get a nice "string is not a number" here when you fix the above missing y
    async myTest3({x, y}: Point) {
    }
}

On a second thought we may put the test metadata in an array instead of map, so tests could preserve their state:
interface Prototype extends Object {
    [testsSymbol]?: {
        [key: string | symbol]: TestOptions
    }
}

to become something like:
interface Prototype extends Object {
    [testsSymbol]?: {
      propertyKey: string | symbol,
      options: TestOptions,
    }[];
}

@pana-cc TLDR;-) This sounds very complicated to me. I was going for making the overall API, both internal and external, to be both more simple to use and understand.
However, along with that I would like to make the @params decorator something that one can use multiple times, along with specific test naming, e.g.
@suite
class foo {

  @test
  @params({name: (params: any) => `params[0] ...`}, [params...])
  @params({pending: true, name: (params: any) => `params[0] ...`}, [params...])
  test(params: any) {}
}

where one can have multiple @params decorators on a test method, each with their own naming scheme,
alongside optional pending/only/skip etc.
similar to @before/@after on the class level.

@pana-cc I would further like to change the overall behaviour so that the test instance is created once only, keeping its state across all test cases unless beforeEach/afterEach modifies that state.
The current approach, where the test instance is recreated before each test and then torn down after each test makes the beforeEach and afterEach rather useless as no state can be kept between tests.

My perspective is test specific state is stored in instance variables and methods, and state shared between tests is stored in static variables and methods.
xUnit.net I think works that way.
MSTest too has static class initialiser and cleanup, but creates a class instance per test.
What I would love to do is have static test methods added as feature. Within static methods in TypeScript you can use ‘this’ to access static properties. So it will be a user choice whether to use instance methods with clean test context, or static test methods with shared test context.
Another thing we could do - add an option in the suite whether to construct a clean new instance for each test or to share a single class instance between each test. I think the code won’t be that iff-y. The instance will either be created and destroyed beforeEach/afterEach or beforeAll/afterAll.

Right, I gave up trying to strongly type the @test with params , we can keep the @test relatively clean and do the @params in a separate decorator.

BTW, the properties on @test do not overload too much the API. We could use ‘@test’ for vanilla tests, and something like ‘@test.params(options, paramsArr)’ that way the params naming function can’t be defined along a name in test.

@pana-cc I am currently looking into suite/test execution modifiers, i.e. only, skip, and pending.
Having these as options in the suite options or test options will require the user to
@suite({only: true|condition})
or
@test({only: true|condition})

whereas
@suite({name:...})
@only

or

@test({name:...})
@params(...)
@skip(condition)

seems to be more intuitive and much easier to use.

Closing in favor of #315

authors: panayot-cankov silkentrance

repo: testdeck/testdeck


text:
ERROR： test-ai-classifier@4.0.2 install error->node-gyp rebuild,No such file or directory

Version info：

npm@6.4.1
node@v10.15.0
Appium@1.16.0
CentOS Linux release 7.4.1708

Install directory：
cd /root/download/node-v10.15.0-linux-x64/lib/node_modules/appium

Error info：

node-pre-gyp WARN Using request for node-pre-gyp https download
[grpc] Success: "/root/download/node-v10.15.0-linux-x64/lib/node_modules/_appium@1.16.0@appium/node_modules/grpc/src/node/extension_binary/node-v64-linux-x64-glibc/grpc_node.node" is installed via remote

test-ai-classifier@4.0.2 install /root/download/node-v10.15.0-linux-x64/lib/node_modules/_appium@1.16.0@appium/node_modules/test-ai-classifier
node-gyp rebuild

make: Entering directory `/root/download/node-v10.15.0-linux-x64/lib/node_modules/_appium@1.16.0@appium/node_modules/test-ai-classifier/build'
CXX(target) Release/obj.target/test-ai-classifier/cc/main.o

In file included from ../cc/main.cc:3:0:
../cc/detection.h:6:83: fatal error: ../node_modules/@tensorflow/tfjs-node/deps/include/tensorflow/c/c_api.h: No such file or directory
#include "../node_modules/@tensorflow/tfjs-node/deps/include/tensorflow/c/c_api.h"
^
compilation terminated.

Question: is this caused by the wrong path in this file""test-ai-classifier/cc/main.cc""?
-[error file]:/root/download/node-v10.15.0-linux-x64/lib/node_modules/_appium@1.16.0@appium/node_modules/test-ai-classifier/cc/main.cc
-[ error line]:#include "../node_modules/@tensorflow/tfjs-node/deps/include/tensorflow/c/c_api.h"
-[tensorflow directory]：
/root/download/node-v10.15.0-linux-x64/lib/node_modules/_appium@1.16.0@appium/node_modules/@tensorflow/tfjs-node/deps/include/tensorflow

hi @sjywzz , you should install tensorflow/tfjs-node in folder Appium before install plugin test-ai-classifier. Because during the installation process, the plugin run build.
https://www.npmjs.com/package/@tensorflow/tfjs-node

oh yes! thanks~~~~

authors: dutradev sjywzz

repo: testdotai/appium-classifier-plugin


text:
traefik file in docker are not accessing

please review my pull request i solve the issue.

@oyekamal I am getting Bad request at http://django.localhost:8008/ how did you resolved that?

Check pull request

Check pull request

@oyekamal after replacing $PWD with ./ I am still seeing Bad gateway.

Share the code link

repo: testdrivenio/django-docker-traefik