Search code examples
dockerterraformamazon-ecsterraform-provider-aws

Provided region_name '"$region"' doesn't match a supported format for Windows (CMD)


I am trying to deploy ECS using Terraform and it's throwing the above error while I am Provisioning the ECR this is happening. It tried removing the double quotes, then enabled trace for troubleshooting. I tried updating to the latest version of terraform as well (v 1.1.2)

Here is the code chunk from main.tf file

# Inherit configuration from CLI tools.  No nice way to pull in the region from ~/.aws/config

provider "aws" {
  region = var.region
  profile = var.profile
}

resource "null_resource" "push" {
  provisioner "local-exec" {
    command = <<EOF
aws ecr get-login-password --region "$region" | docker login --username AWS --password-stdin "$ecr_fqdn"
docker tag "servian/techchallengeapp:latest" "$repository"
docker push "$repository:latest"
docker logout "$ecr_fqdn"
EOF

    environment = {
      ecr_fqdn = regex("^([^/]*)/", aws_ecr_repository.ecs.repository_url).0
      region = var.region
      repository = aws_ecr_repository.ecs.repository_url
    }
  }
  depends_on = [aws_ecr_repository.ecs]
}

The code chunk from the variable.tf file

variable "region" {
     description = "Region to deploy app"
     default = "ap-southeast-2"
   }

Please find the error below

null_resource.push: Creating...
2022-01-04T13:50:08.315+1100 [INFO]  Starting apply for null_resource.push
2022-01-04T13:50:08.315+1100 [DEBUG] null_resource.push: applying the planned Create change
2022-01-04T13:50:08.315+1100 [TRACE] GRPCProvider: ApplyResourceChange
2022-01-04T13:50:08.315+1100 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState to workingState for null_resource.push
2022-01-04T13:50:08.315+1100 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState: writing state object for null_resource.push
2022-01-04T13:50:08.315+1100 [TRACE] applyProvisioners: provisioning null_resource.push with "local-exec"
null_resource.push: Provisioning with 'local-exec'...
null_resource.push (local-exec): Executing: ["cmd" "/C" "aws ecr get-login-password --region \"$region\" | docker login --username AWS --password-stdin \"$ecr_fqdn\"\r\ndocker tag \"servian/techchallengeapp:latest\" \"$repository\"\r\ndocker push \"$repository:latest\"\r\ndocker logout \"$ecr_fqdn\"\r\n"]

null_resource.push (local-exec): **Provided region_name '"$region"' doesn't match a supported format.**
null_resource.push (local-exec): Error: Cannot perform an interactive login from a non TTY device
2022-01-04T13:50:09.038+1100 [WARN]  Errors while provisioning null_resource.push with "local-exec", so aborting
2022-01-04T13:50:09.038+1100 [TRACE] evalApplyProvisioners: null_resource.push provisioning failed, but we will continue anyway at the caller's request
2022-01-04T13:50:09.038+1100 [TRACE] maybeTainted: null_resource.push encountered an error during creation, so it is now marked as tainted
2022-01-04T13:50:09.038+1100 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState to workingState for null_resource.push
2022-01-04T13:50:09.038+1100 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState: writing state object for null_resource.push
2022-01-04T13:50:09.038+1100 [TRACE] statemgr.Filesystem: have already backed up original terraform.tfstate to terraform.tfstate.backup on a previous write
2022-01-04T13:50:09.040+1100 [TRACE] statemgr.Filesystem: state has changed since last snapshot, so incrementing serial to 85
2022-01-04T13:50:09.040+1100 [TRACE] statemgr.Filesystem: writing snapshot at terraform.tfstate
2022-01-04T13:50:09.046+1100 [TRACE] vertex "null_resource.push": visit complete
2022-01-04T13:50:09.046+1100 [TRACE] dag/walk: upstream of "aws_ecs_task_definition.ecs" errored, so skipping
2022-01-04T13:50:09.046+1100 [TRACE] dag/walk: upstream of "null_resource.updatedb" errored, so skipping
2022-01-04T13:50:09.046+1100 [TRACE] dag/walk: upstream of "provider[\"registry.terraform.io/hashicorp/null\"] (close)" errored, so skipping
2022-01-04T13:50:09.047+1100 [TRACE] dag/walk: upstream of "aws_ecs_service.ecs" errored, so skipping
2022-01-04T13:50:09.047+1100 [TRACE] dag/walk: upstream of "provider[\"registry.terraform.io/hashicorp/aws\"] (close)" errored, so skipping
2022-01-04T13:50:09.047+1100 [TRACE] dag/walk: upstream of "meta.count-boundary (EachMode fixup)" errored, so skipping
2022-01-04T13:50:09.047+1100 [TRACE] dag/walk: upstream of "root" errored, so skipping
2022-01-04T13:50:09.047+1100 [TRACE] statemgr.Filesystem: have already backed up original terraform.tfstate to terraform.tfstate.backup on a previous write
2022-01-04T13:50:09.049+1100 [TRACE] statemgr.Filesystem: state has changed since last snapshot, so incrementing serial to 86
2022-01-04T13:50:09.049+1100 [TRACE] statemgr.Filesystem: writing snapshot at terraform.tfstate
╷
│ Error: local-exec provisioner error
│
│   with null_resource.push,
│   on main.tf line 191, in resource "null_resource" "push":
│  191:   provisioner "local-exec" {
│
│ Error running command 'aws ecr get-login-password --region "$region" |
│ docker login --username AWS --password-stdin "$ecr_fqdn"
│ docker tag "servian/techchallengeapp:latest" "$repository"
│ docker push "$repository:latest"
│ docker logout "$ecr_fqdn"
│ ': exit status 1. Output:
│ Provided region_name '"$region"' doesn't match a supported format.
│ Error: Cannot perform an interactive login from a non TTY device
│
╵
2022-01-04T13:50:09.053+1100 [TRACE] statemgr.Filesystem: removing lock metadata file .terraform.tfstate.lock.info
2022-01-04T13:50:09.053+1100 [TRACE] statemgr.Filesystem: unlocked by closing terraform.tfstate
2022-01-04T13:50:09.054+1100 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = transport is closing"
2022-01-04T13:50:09.054+1100 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = transport is closing"
2022-01-04T13:50:09.064+1100 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/hashicorp/null/3.1.0/windows_amd64/terraform-provider-null_v3.1.0_x5.exe pid=38252
2022-01-04T13:50:09.064+1100 [DEBUG] provider: plugin exited
2022-01-04T13:50:09.070+1100 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/hashicorp/aws/3.70.0/windows_amd64/terraform-provider-aws_v3.70.0_x5.exe pid=31016
2022-01-04T13:50:09.070+1100 [DEBUG] provider: plugin exited

Ì have checked my AWS region as well

    $ aws configure get region
     ap-southeast-2


Solution

  • Updated:

    A ${ ... } sequence is an interpolation in Terraform's configuration language, which evaluates the expression given between the markers. Unix shells typically use $..

    As per the official documentation, the command is evaluated in a shell, and can use environment variables or Terraform variables. So, basically, what you are trying to achieve should work fundamentally.

    I did a quick test and I was able to successfully apply that locally:

    with double quotes

    null_resource.ecr_login: Creating...
    null_resource.ecr_login: Provisioning with 'local-exec'...
    null_resource.ecr_login (local-exec): Executing: ["/bin/sh" "-c" "aws ecr get-login-password --region \"$region\" | docker login --username AWS --password-stdin \"$ecr_fqdn\"\n"]
    null_resource.ecr_login (local-exec): Login Succeeded
    null_resource.ecr_login: Creation complete after 2s [id=6191522068151349753]
    
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    

    Without double quotes:

    null_resource.ecr_login: Creating...
    null_resource.ecr_login: Provisioning with 'local-exec'...
    null_resource.ecr_login (local-exec): Executing: ["/bin/sh" "-c" "aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $ecr_fqdn\n"]
    null_resource.ecr_login (local-exec): Login Succeeded
    null_resource.ecr_login: Creation complete after 2s [id=931251830265041579]
    
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    

    Now, let's look at the error you are encountering:

    null_resource.push: Provisioning with 'local-exec'...
    null_resource.push (local-exec): Executing: ["cmd" "/C" "aws ecr get-login-password --region \"$region\" | docker login --username AWS --password-stdin \"$ecr_fqdn\"\r\ndocker tag \"servian/techchallengeapp:latest\" \"$repository\"\r\ndocker push \"$repository:latest\"\r\ndocker logout \"$ecr_fqdn\"\r\n"]
    
    null_resource.push (local-exec): **Provided region_name '"$region"' doesn't match a supported format.**
    null_resource.push (local-exec): Error: Cannot perform an interactive login from a non TTY device
    2022-01-04T13:50:09.038+1100 [WARN]  Errors while provisioning null_resource.push with "local-exec", so aborting
    

    It seems like you are trying to execute these commands on Windows Command Prompt, that too with the quotes and somehow the CMD doesn't know what to do with it. Here's a similar issue.

    Anyway, I would recommend doing the regex operation in terraform locals block and then simply using terraform native variable and local values.

    Something like this:

    locals{
      ecr_fqdn = regex("^([^/]*)/", aws_ecr_repository.ecs.repository_url.0
    }
    

    and the null_resource:

    resource "null_resource" "push" {
      provisioner "local-exec" {
        command = <<EOF
    aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${local.ecr_fqdn}
    docker tag "servian/techchallengeapp:latest" ${aws_ecr_repository.ecs.repository_url}
    docker push "${aws_ecr_repository.ecs.repository_url}:latest"
    docker logout ${local.ecr_fqdn}
    EOF
      }
      depends_on = [aws_ecr_repository.ecs]
    }