terraform-aws-modules / terraform-aws-apigateway-v2

Terraform module to create AWS API Gateway v2 (HTTP/WebSocket) 🇺🇦
https://registry.terraform.io/modules/terraform-aws-modules/apigateway-v2/aws
Apache License 2.0
144 stars 188 forks source link

feat: Add support for tls_config in integrations #51

Closed sharath-sequoia closed 2 years ago

sharath-sequoia commented 2 years ago

Description

Custom domain for integration requires us to provide tls_config for the integration, which API Gateway uses to verify the hostname on the integration's certificate. It was not possible to include this configuration in this module, and this change would allow us to pass this configuration within the integrations variable.

Motivation and Context

Earlier, there was no option to include tls_config configuration for the API gateway integrations using this module. I have now added a dynamic block to include this configuration if it is present in the integrations input variable. Fixes #47.

Breaking Changes

There are no breaking changes included.

How Has This Been Tested?

antonbabenko commented 2 years ago

Hi!

Please run the example code and paste the output of the plan here.

Also, run pre-commit run -a to fix the formatting of the code.

sharath-sequoia commented 2 years ago

@antonbabenko, Thanks for the help. I have now run the pre-commit hooks, which made some changes to the files. I have also made a fix for the input value (uses jsonencode) and verified the changes by doing a terraform plan locally, you can find the output below. Please review.

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
 <= read (data resources)

Terraform will perform the following actions:

  # aws_apigatewayv2_authorizer.some_authorizer will be created
  + resource "aws_apigatewayv2_authorizer" "some_authorizer" {
      + api_id                           = (known after apply)
      + authorizer_result_ttl_in_seconds = (known after apply)
      + authorizer_type                  = "JWT"
      + id                               = (known after apply)
      + identity_sources                 = [
          + "$request.header.Authorization",
        ]
      + name                             = (known after apply)

      + jwt_configuration {
          + audience = [
              + "example",
            ]
          + issuer   = (known after apply)
        }
    }

  # aws_cloudwatch_log_group.logs will be created
  + resource "aws_cloudwatch_log_group" "logs" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + name              = (known after apply)
      + retention_in_days = 0
      + tags_all          = (known after apply)
    }

  # aws_cognito_user_pool.this will be created
  + resource "aws_cognito_user_pool" "this" {
      + arn                        = (known after apply)
      + creation_date              = (known after apply)
      + custom_domain              = (known after apply)
      + domain                     = (known after apply)
      + email_verification_message = (known after apply)
      + email_verification_subject = (known after apply)
      + endpoint                   = (known after apply)
      + estimated_number_of_users  = (known after apply)
      + id                         = (known after apply)
      + last_modified_date         = (known after apply)
      + mfa_configuration          = "OFF"
      + name                       = (known after apply)
      + sms_verification_message   = (known after apply)
      + tags_all                   = (known after apply)

      + admin_create_user_config {
          + allow_admin_create_user_only = (known after apply)

          + invite_message_template {
              + email_message = (known after apply)
              + email_subject = (known after apply)
              + sms_message   = (known after apply)
            }
        }

      + lambda_config {
          + create_auth_challenge          = (known after apply)
          + custom_message                 = (known after apply)
          + define_auth_challenge          = (known after apply)
          + kms_key_id                     = (known after apply)
          + post_authentication            = (known after apply)
          + post_confirmation              = (known after apply)
          + pre_authentication             = (known after apply)
          + pre_sign_up                    = (known after apply)
          + pre_token_generation           = (known after apply)
          + user_migration                 = (known after apply)
          + verify_auth_challenge_response = (known after apply)

          + custom_email_sender {
              + lambda_arn     = (known after apply)
              + lambda_version = (known after apply)
            }

          + custom_sms_sender {
              + lambda_arn     = (known after apply)
              + lambda_version = (known after apply)
            }
        }

      + password_policy {
          + minimum_length                   = (known after apply)
          + require_lowercase                = (known after apply)
          + require_numbers                  = (known after apply)
          + require_symbols                  = (known after apply)
          + require_uppercase                = (known after apply)
          + temporary_password_validity_days = (known after apply)
        }

      + sms_configuration {
          + external_id    = (known after apply)
          + sns_caller_arn = (known after apply)
        }

      + verification_message_template {
          + default_email_option  = (known after apply)
          + email_message         = (known after apply)
          + email_message_by_link = (known after apply)
          + email_subject         = (known after apply)
          + email_subject_by_link = (known after apply)
          + sms_message           = (known after apply)
        }
    }

  # aws_route53_record.api will be created
  + resource "aws_route53_record" "api" {
      + allow_overwrite = (known after apply)
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = "complete-http"
      + type            = "A"
      + zone_id         = "Z0300236383DVX6K5HD6E"

      + alias {
          + evaluate_target_health = false
          + name                   = (known after apply)
          + zone_id                = (known after apply)
        }
    }

  # aws_s3_bucket.truststore will be created
  + resource "aws_s3_bucket" "truststore" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = (known after apply)
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + versioning {
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        }
    }

  # aws_s3_bucket_object.truststore will be created
  + resource "aws_s3_bucket_object" "truststore" {
      + acl                    = "private"
      + bucket                 = (known after apply)
      + bucket_key_enabled     = (known after apply)
      + content                = (known after apply)
      + content_type           = (known after apply)
      + etag                   = (known after apply)
      + force_destroy          = false
      + id                     = (known after apply)
      + key                    = "truststore.pem"
      + kms_key_id             = (known after apply)
      + server_side_encryption = "AES256"
      + storage_class          = (known after apply)
      + tags_all               = (known after apply)
      + version_id             = (known after apply)
    }

  # null_resource.download_package will be created
  + resource "null_resource" "download_package" {
      + id       = (known after apply)
      + triggers = {
          + "downloaded" = "downloaded_package_19df9467424e9a2bd05d15f02e34875d.zip"
        }
    }

  # random_pet.this will be created
  + resource "random_pet" "this" {
      + id        = (known after apply)
      + length    = 2
      + separator = "-"
    }

  # tls_private_key.private_key will be created
  + resource "tls_private_key" "private_key" {
      + algorithm                  = "RSA"
      + ecdsa_curve                = "P224"
      + id                         = (known after apply)
      + private_key_pem            = (sensitive value)
      + public_key_fingerprint_md5 = (known after apply)
      + public_key_openssh         = (known after apply)
      + public_key_pem             = (known after apply)
      + rsa_bits                   = 2048
    }

  # tls_self_signed_cert.example will be created
  + resource "tls_self_signed_cert" "example" {
      + allowed_uses          = [
          + "cert_signing",
          + "server_auth",
        ]
      + cert_pem              = (known after apply)
      + early_renewal_hours   = 0
      + id                    = (known after apply)
      + is_ca_certificate     = true
      + key_algorithm         = "RSA"
      + private_key_pem       = (sensitive value)
      + ready_for_renewal     = true
      + validity_end_time     = (known after apply)
      + validity_period_hours = 12
      + validity_start_time   = (known after apply)

      + subject {
          + common_name  = "example.com"
          + organization = "ACME Examples, Inc"
        }
    }

  # module.acm.aws_acm_certificate.this[0] will be created
  + resource "aws_acm_certificate" "this" {
      + arn                       = (known after apply)
      + domain_name               = "terraform-aws-modules.modules.tf"
      + domain_validation_options = [
          + {
              + domain_name           = "complete-http.terraform-aws-modules.modules.tf"
              + resource_record_name  = (known after apply)
              + resource_record_type  = (known after apply)
              + resource_record_value = (known after apply)
            },
          + {
              + domain_name           = "terraform-aws-modules.modules.tf"
              + resource_record_name  = (known after apply)
              + resource_record_type  = (known after apply)
              + resource_record_value = (known after apply)
            },
        ]
      + id                        = (known after apply)
      + status                    = (known after apply)
      + subject_alternative_names = [
          + "complete-http.terraform-aws-modules.modules.tf",
        ]
      + tags_all                  = (known after apply)
      + validation_emails         = (known after apply)
      + validation_method         = "DNS"

      + options {
          + certificate_transparency_logging_preference = "ENABLED"
        }
    }

  # module.acm.aws_acm_certificate_validation.this[0] will be created
  + resource "aws_acm_certificate_validation" "this" {
      + certificate_arn         = (known after apply)
      + id                      = (known after apply)
      + validation_record_fqdns = (known after apply)
    }

  # module.acm.aws_route53_record.validation[0] will be created
  + resource "aws_route53_record" "validation" {
      + allow_overwrite = true
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = (known after apply)
      + records         = (known after apply)
      + ttl             = 60
      + type            = (known after apply)
      + zone_id         = "Z0300236383DVX6K5HD6E"
    }

  # module.acm.aws_route53_record.validation[1] will be created
  + resource "aws_route53_record" "validation" {
      + allow_overwrite = true
      + fqdn            = (known after apply)
      + id              = (known after apply)
      + name            = (known after apply)
      + records         = (known after apply)
      + ttl             = 60
      + type            = (known after apply)
      + zone_id         = "Z0300236383DVX6K5HD6E"
    }

  # module.api_gateway.aws_apigatewayv2_api.this[0] will be created
  + resource "aws_apigatewayv2_api" "this" {
      + api_endpoint                 = (known after apply)
      + api_key_selection_expression = "$request.header.x-api-key"
      + arn                          = (known after apply)
      + body                         = (known after apply)
      + description                  = "My awesome HTTP API Gateway"
      + disable_execute_api_endpoint = false
      + execution_arn                = (known after apply)
      + id                           = (known after apply)
      + name                         = (known after apply)
      + protocol_type                = "HTTP"
      + route_selection_expression   = "$request.method $request.path"
      + tags                         = {
          + "Name" = "dev-api-new"
        }
      + tags_all                     = {
          + "Name" = "dev-api-new"
        }

      + cors_configuration {
          + allow_headers = [
              + "authorization",
              + "content-type",
              + "x-amz-date",
              + "x-amz-security-token",
              + "x-amz-user-agent",
              + "x-api-key",
            ]
          + allow_methods = [
              + "*",
            ]
          + allow_origins = [
              + "*",
            ]
        }
    }

  # module.api_gateway.aws_apigatewayv2_api_mapping.this[0] will be created
  + resource "aws_apigatewayv2_api_mapping" "this" {
      + api_id      = (known after apply)
      + domain_name = (known after apply)
      + id          = (known after apply)
      + stage       = (known after apply)
    }

  # module.api_gateway.aws_apigatewayv2_domain_name.this[0] will be created
  + resource "aws_apigatewayv2_domain_name" "this" {
      + api_mapping_selection_expression = (known after apply)
      + arn                              = (known after apply)
      + domain_name                      = "terraform-aws-modules.modules.tf"
      + id                               = (known after apply)
      + tags                             = {
          + "Name" = "dev-api-new"
        }
      + tags_all                         = {
          + "Name" = "dev-api-new"
        }

      + domain_name_configuration {
          + certificate_arn    = (known after apply)
          + endpoint_type      = "REGIONAL"
          + hosted_zone_id     = (known after apply)
          + security_policy    = "TLS_1_2"
          + target_domain_name = (known after apply)
        }

      + mutual_tls_authentication {
          + truststore_uri     = (known after apply)
          + truststore_version = (known after apply)
        }
    }

  # module.api_gateway.aws_apigatewayv2_integration.this["$default"] will be created
  + resource "aws_apigatewayv2_integration" "this" {
      + api_id                                    = (known after apply)
      + connection_id                             = (known after apply)
      + connection_type                           = (known after apply)
      + content_handling_strategy                 = (known after apply)
      + credentials_arn                           = (known after apply)
      + description                               = (known after apply)
      + id                                        = (known after apply)
      + integration_method                        = (known after apply)
      + integration_response_selection_expression = (known after apply)
      + integration_subtype                       = (known after apply)
      + integration_type                          = (known after apply)
      + integration_uri                           = (known after apply)
      + passthrough_behavior                      = (known after apply)
      + payload_format_version                    = (known after apply)
      + timeout_milliseconds                      = (known after apply)

      + tls_config {
          + server_name_to_verify = (known after apply)
        }
    }

  # module.api_gateway.aws_apigatewayv2_integration.this["ANY /"] will be created
  + resource "aws_apigatewayv2_integration" "this" {
      + api_id                                    = (known after apply)
      + connection_id                             = (known after apply)
      + connection_type                           = (known after apply)
      + content_handling_strategy                 = (known after apply)
      + credentials_arn                           = (known after apply)
      + description                               = (known after apply)
      + id                                        = (known after apply)
      + integration_method                        = (known after apply)
      + integration_response_selection_expression = (known after apply)
      + integration_subtype                       = (known after apply)
      + integration_type                          = (known after apply)
      + integration_uri                           = (known after apply)
      + passthrough_behavior                      = (known after apply)
      + payload_format_version                    = (known after apply)
      + timeout_milliseconds                      = (known after apply)

      + tls_config {
          + server_name_to_verify = (known after apply)
        }
    }

  # module.api_gateway.aws_apigatewayv2_integration.this["GET /some-route"] will be created
  + resource "aws_apigatewayv2_integration" "this" {
      + api_id                                    = (known after apply)
      + connection_id                             = (known after apply)
      + connection_type                           = (known after apply)
      + content_handling_strategy                 = (known after apply)
      + credentials_arn                           = (known after apply)
      + description                               = (known after apply)
      + id                                        = (known after apply)
      + integration_method                        = (known after apply)
      + integration_response_selection_expression = (known after apply)
      + integration_subtype                       = (known after apply)
      + integration_type                          = (known after apply)
      + integration_uri                           = (known after apply)
      + passthrough_behavior                      = (known after apply)
      + payload_format_version                    = (known after apply)
      + timeout_milliseconds                      = (known after apply)

      + tls_config {
          + server_name_to_verify = (known after apply)
        }
    }

  # module.api_gateway.aws_apigatewayv2_integration.this["POST /start-step-function"] will be created
  + resource "aws_apigatewayv2_integration" "this" {
      + api_id                                    = (known after apply)
      + connection_id                             = (known after apply)
      + connection_type                           = (known after apply)
      + content_handling_strategy                 = (known after apply)
      + credentials_arn                           = (known after apply)
      + description                               = (known after apply)
      + id                                        = (known after apply)
      + integration_method                        = (known after apply)
      + integration_response_selection_expression = (known after apply)
      + integration_subtype                       = (known after apply)
      + integration_type                          = (known after apply)
      + integration_uri                           = (known after apply)
      + passthrough_behavior                      = (known after apply)
      + payload_format_version                    = (known after apply)
      + request_parameters                        = (known after apply)
      + timeout_milliseconds                      = (known after apply)

      + tls_config {
          + server_name_to_verify = (known after apply)
        }
    }

  # module.api_gateway.aws_apigatewayv2_route.this["$default"] will be created
  + resource "aws_apigatewayv2_route" "this" {
      + api_id                              = (known after apply)
      + api_key_required                    = (known after apply)
      + authorization_type                  = (known after apply)
      + authorizer_id                       = (known after apply)
      + id                                  = (known after apply)
      + model_selection_expression          = (known after apply)
      + operation_name                      = (known after apply)
      + route_key                           = "$default"
      + route_response_selection_expression = (known after apply)
      + target                              = (known after apply)
    }

  # module.api_gateway.aws_apigatewayv2_route.this["ANY /"] will be created
  + resource "aws_apigatewayv2_route" "this" {
      + api_id                              = (known after apply)
      + api_key_required                    = (known after apply)
      + authorization_type                  = (known after apply)
      + authorizer_id                       = (known after apply)
      + id                                  = (known after apply)
      + model_selection_expression          = (known after apply)
      + operation_name                      = (known after apply)
      + route_key                           = "ANY /"
      + route_response_selection_expression = (known after apply)
      + target                              = (known after apply)
    }

  # module.api_gateway.aws_apigatewayv2_route.this["GET /some-route"] will be created
  + resource "aws_apigatewayv2_route" "this" {
      + api_id                              = (known after apply)
      + api_key_required                    = (known after apply)
      + authorization_type                  = (known after apply)
      + authorizer_id                       = (known after apply)
      + id                                  = (known after apply)
      + model_selection_expression          = (known after apply)
      + operation_name                      = (known after apply)
      + route_key                           = "GET /some-route"
      + route_response_selection_expression = (known after apply)
      + target                              = (known after apply)
    }

  # module.api_gateway.aws_apigatewayv2_route.this["POST /start-step-function"] will be created
  + resource "aws_apigatewayv2_route" "this" {
      + api_id                              = (known after apply)
      + api_key_required                    = (known after apply)
      + authorization_type                  = (known after apply)
      + authorizer_id                       = (known after apply)
      + id                                  = (known after apply)
      + model_selection_expression          = (known after apply)
      + operation_name                      = (known after apply)
      + route_key                           = "POST /start-step-function"
      + route_response_selection_expression = (known after apply)
      + target                              = (known after apply)
    }

  # module.api_gateway.aws_apigatewayv2_stage.default[0] will be created
  + resource "aws_apigatewayv2_stage" "default" {
      + api_id        = (known after apply)
      + arn           = (known after apply)
      + auto_deploy   = true
      + deployment_id = (known after apply)
      + execution_arn = (known after apply)
      + id            = (known after apply)
      + invoke_url    = (known after apply)
      + name          = "$default"
      + tags          = {
          + "Name" = "dev-api-new"
        }
      + tags_all      = {
          + "Name" = "dev-api-new"
        }

      + access_log_settings {
          + destination_arn = (known after apply)
          + format          = (known after apply)
        }

      + default_route_settings {
          + data_trace_enabled       = false
          + detailed_metrics_enabled = true
          + logging_level            = (known after apply)
          + throttling_burst_limit   = 100
          + throttling_rate_limit    = 100
        }
    }

  # module.lambda_function.data.aws_iam_policy_document.logs[0] will be read during apply
  # (config refers to values not yet known)
 <= data "aws_iam_policy_document" "logs"  {
      + id   = (known after apply)
      + json = (known after apply)

      + statement {
          + actions   = [
              + "logs:CreateLogGroup",
              + "logs:CreateLogStream",
              + "logs:PutLogEvents",
            ]
          + effect    = "Allow"
          + resources = [
              + (known after apply),
              + (known after apply),
            ]
        }
    }

  # module.lambda_function.aws_cloudwatch_log_group.lambda[0] will be created
  + resource "aws_cloudwatch_log_group" "lambda" {
      + arn               = (known after apply)
      + id                = (known after apply)
      + name              = (known after apply)
      + retention_in_days = 0
      + tags_all          = (known after apply)
    }

  # module.lambda_function.aws_iam_policy.logs[0] will be created
  + resource "aws_iam_policy" "logs" {
      + arn       = (known after apply)
      + id        = (known after apply)
      + name      = (known after apply)
      + path      = "/"
      + policy    = (known after apply)
      + policy_id = (known after apply)
      + tags_all  = (known after apply)
    }

  # module.lambda_function.aws_iam_policy_attachment.logs[0] will be created
  + resource "aws_iam_policy_attachment" "logs" {
      + id         = (known after apply)
      + name       = (known after apply)
      + policy_arn = (known after apply)
      + roles      = (known after apply)
    }

  # module.lambda_function.aws_iam_role.lambda[0] will be created
  + resource "aws_iam_role" "lambda" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "lambda.amazonaws.com"
                        }
                      + Sid       = ""
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = true
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy {
          + name   = (known after apply)
          + policy = (known after apply)
        }
    }

  # module.lambda_function.aws_lambda_function.this[0] will be created
  + resource "aws_lambda_function" "this" {
      + arn                            = (known after apply)
      + description                    = "My awesome lambda function"
      + filename                       = "downloaded_package_19df9467424e9a2bd05d15f02e34875d.zip"
      + function_name                  = (known after apply)
      + handler                        = "index.lambda_handler"
      + id                             = (known after apply)
      + invoke_arn                     = (known after apply)
      + last_modified                  = (known after apply)
      + memory_size                    = 128
      + package_type                   = "Zip"
      + publish                        = true
      + qualified_arn                  = (known after apply)
      + reserved_concurrent_executions = -1
      + role                           = (known after apply)
      + runtime                        = "python3.8"
      + signing_job_arn                = (known after apply)
      + signing_profile_version_arn    = (known after apply)
      + source_code_hash               = (known after apply)
      + source_code_size               = (known after apply)
      + tags_all                       = (known after apply)
      + timeout                        = 3
      + version                        = (known after apply)

      + tracing_config {
          + mode = (known after apply)
        }
    }

  # module.lambda_function.aws_lambda_permission.current_version_triggers["AllowExecutionFromAPIGateway"] will be created
  + resource "aws_lambda_permission" "current_version_triggers" {
      + action             = (known after apply)
      + event_source_token = (known after apply)
      + function_name      = (known after apply)
      + id                 = (known after apply)
      + principal          = (known after apply)
      + qualifier          = (known after apply)
      + source_account     = (known after apply)
      + source_arn         = (known after apply)
      + statement_id       = (known after apply)
    }

  # module.lambda_function.aws_lambda_permission.unqualified_alias_triggers["AllowExecutionFromAPIGateway"] will be created
  + resource "aws_lambda_permission" "unqualified_alias_triggers" {
      + action             = (known after apply)
      + event_source_token = (known after apply)
      + function_name      = (known after apply)
      + id                 = (known after apply)
      + principal          = (known after apply)
      + source_account     = (known after apply)
      + source_arn         = (known after apply)
      + statement_id       = (known after apply)
    }

  # module.step_function.aws_iam_role.this[0] will be created
  + resource "aws_iam_role" "this" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "states.eu-west-1.amazonaws.com"
                        }
                      + Sid       = ""
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = true
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy {
          + name   = (known after apply)
          + policy = (known after apply)
        }
    }

  # module.step_function.aws_sfn_state_machine.this[0] will be created
  + resource "aws_sfn_state_machine" "this" {
      + arn           = (known after apply)
      + creation_date = (known after apply)
      + definition    = jsonencode(
            {
              + Comment = "A Hello World example of the Amazon States Language using Pass states"
              + StartAt = "Hello"
              + States  = {
                  + Hello = {
                      + Next   = "World"
                      + Result = "Hello"
                      + Type   = "Pass"
                    }
                  + World = {
                      + End    = true
                      + Result = "World"
                      + Type   = "Pass"
                    }
                }
            }
        )
      + id            = (known after apply)
      + name          = (known after apply)
      + role_arn      = (known after apply)
      + status        = (known after apply)
      + tags          = (known after apply)
      + tags_all      = (known after apply)
      + type          = "STANDARD"

      + logging_configuration {
          + include_execution_data = (known after apply)
          + level                  = (known after apply)
          + log_destination        = (known after apply)
        }

      + tracing_configuration {
          + enabled = (known after apply)
        }
    }

Plan: 35 to add, 0 to change, 0 to destroy.
antonbabenko commented 2 years ago

Thanks, @sharath-sequoia !

v1.2.0 has been just released.

github-actions[bot] commented 1 year ago

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.