Baran Karaaslan
Baran Karaaslan

Reputation: 23

Terraform docker_registry_image error: 'unable to get digest: Got bad response from registry: 400 Bad Request'

I am trying to use CDF for terraform to build and push a docker image to AWS ECR. I have decided to use terraform docker provider for it. Here is my code


class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    const usProvider = new aws.AwsProvider(this, "us-provider", {
      region: "us-east-1",
      defaultTags: {
        tags: {
          Project: "CV",
          Name: "CV",
        },
      },
    });
    const repo = new aws.ecr.EcrpublicRepository(this, "docker-repo", {
      provider: usProvider,
      repositoryName: "cv",
      forceDestroy: true,
    });
    const authToken = new aws.ecr.DataAwsEcrpublicAuthorizationToken(
      this,
      "auth-token",
      {
        provider: usProvider,
      }
    );
    new docker.DockerProvider(this, "docker-provider", {
      registryAuth: [
        {
          address: repo.repositoryUri,
          username: authToken.userName,
          password: authToken.password,
        },
      ],
    });
    new docker.RegistryImage(this, "image-on-public-ecr", {
      name: repo.repositoryUri,
      buildAttribute: {
        context: __dirname,
      },
    });
  }
}

But during deployment, I have this error: Unable to create image, image not found: unable to get digest: Got bad response from registry: 400 Bad Request. But it still is able to push to the registry, I can see it from the AWS console.

I can't seem to find any mistake in my code, and I don't understand the error. I hope you can help

Upvotes: 0

Views: 755

Answers (1)

Daniel Schmidt
Daniel Schmidt

Reputation: 11921

In the Terraform execution model is build so that Terraform first finds all the information it needs to get the current state of your infrastructure and the in a second step calculates the plan of changes that need to be applied to get the current state into the that you described through your configuration.

This poses a problem here, the provider you declare is using information that is only available once the plan is being put into action, there is no repo url / auth token before the ECR repo is being created.

There a different ways to solve this problem: You can make use of the cross-stack references / multi-stack feature and split the ECR repo creation into a separate TerraformStack that deploys beforehand. You can pass a value from that stack into your other stack and use it to configure the provider.

Another way to solve this is by building and pushing your image outside of the terraform provider through the null provider with a local provisioner as it's done in the docker-aws-ecs E2E example

Upvotes: 1

Related Questions