Terraform Module with source as Code-Commit

245 Views Asked by At

I have created a S3 resource module with variables being read from variable.tf

resource "aws_s3_bucket" "s3_bucket" {
  bucket = var.bucket_name
  tags = var.tags
}

resource "aws_s3_bucket_logging" "bucket_logging" {
  bucket = aws_s3_bucket.s3_bucket.id

  target_bucket = var.logging_bucket_name
  target_prefix ="log-${aws_s3_bucket.s3_bucket.id}/"
}

The variable.tf looks like this:

variable "bucket_name"{
    type=string
    description="Name of the bucket"
}
variable "tags"{
    type= map(string)
}
variable "logging_bucket_name"{
    type=string
    description="Name of the Logging bucket"
}

This is being stored in a AWS code-commit repository and is being referenced in the main tf pipeline in the following way:

module "s3_bucket"{
  source="git::codecommit://iac-template/module/s3?ref=feature-s3-template"
  bucket_name = "test1"
  tags = local.tags
  logging_bucket_name = "test2"
}

When I run terraform init, the modules are getting downloaded correctly:

Modules correctly downloaded

But the error in 'terraform plan' is:

Error: Unsupported argument
│
│   on main.tf line 3, in module "s3_bucket":
│    3:   bucket_name = "test1"
│
│ An argument named "bucket_name" is not expected here.
╵
╷
│ Error: Unsupported argument
│
│   on main.tf line 4, in module "s3_bucket":
│    4:   tags = local.tags
│
│ An argument named "tags" is not expected here.
╵
╷
│ Error: Unsupported argument
│
│   on main.tf line 5, in module "s3_bucket":
│    5:   logging_bucket_name = "test2"
│
│ An argument named "logging_bucket_name" is not expected here.

Is this some issue with the way I'm referring it from code-commit or am I missing something here.

1

There are 1 best solutions below

1
On

Based on your linked screenshot of the directory tree in your text editor, it seems like your module is in a subdirectory of the repository: module/s3. Terraform is expecting the module source code to be at the root of the repository, and so it's looking in the wrong place to find your variable declarations.

Based on the codecommit:// scheme in your Git URL, I assume you are using git-remote-codecommit to extend Git with support for cloning using this special scheme. That adapter automatically generates an HTTPS URL referring to a CodeCommit repository, and then uses Git's HTTPS cloner to fetch it.

The documented syntax for the codecommit:// scheme is for it to be followed by an optional profile name in the "user" portion of the URL, and then the repository name in the part of the URL that would normally be the hostname in a conventional URL scheme. Your URL includes additional path content /module/s3, which is not documented as being allowed for git-remote-codecommit.

Unfortunately the URL parsing code in git-remote-codecommit seems to just totally ignore the invalid path portion, and so it's interpreting your URL codecommit://iac-template/module/s3 as if you had written just codecommit://iac-template: the /module/s3 part is silently ignored.

Effectively then, you're cloning the entire iac-template repository and Terraform has no information about which path to use within the repository, because that path portion was consumed by git-remote-codecommit instead.

To fix this, it's important to understand how Terraform interprets source addresses for Git repositories:

  • The git:: prefix tells Terraform to interpret the rest of the string as a Git repository source address.
  • The following text, up until either a double slash // or question mark ?, is taken as the URL to pass to git.
  • If there's a double slash delimiter // then that begins a subdirectory path which Terraform should use within the repository.
  • The ? symbol begins the query string, which for Git URLs is interpreted by Terraform itself and the ref argument becomes the branch, tag, etc to select when cloning the repository.

The correct repository URL in your case would be codecommit://iac-template, and the subdirectory portion for Terraform to use is module/s3, so putting those to pieces together with the other information in your source string gives:

  source = "git::codecommit://iac-template//module/s3?ref=feature-s3-template"

That breaks down into the following parts:

  • git:: - selects the Git installation method
  • codecommit://iac-template is the URL to pass to git clone
  • //module/s3 tells Terraform to look for a module in the module/s3 directory inside the repository, once cloned.
  • ?ref=feature-s3-template tells Terraform to select the feature-s3-template branch from the repository.