ハブ記事: Terraform Modules: Complete Guide →
A hub article that covers the full picture of Terraform modules — design, distribution, and operations.
The source argument on a module block is the single source of truth for where a module comes from. Get the syntax wrong and initialization, updates, and pinning all break down.
This article focuses on the three forms — registry / git / local — and zeroes in on real-world pitfalls and the points that show up most often on the Associate exam.
The source argument on a module block is the address Terraform uses to locate the module. The main forms are registry (public/private), git, and local (relative/absolute paths). terraform init resolves the source and fetches the module into .terraform/modules (local sources are referenced in place, not fetched).
The version argument — which lets you constrain a module's version — is only accepted by registry sources. With git you pin via ?ref= (tag, branch, or commit). With local you rely on repository management and release procedures. On the Associate exam, it's important to distinguish exactly which form lets you pin what.
Module source resolution flow (conceptual diagram)
Fetched from the public Terraform Registry or from a Terraform Cloud/Enterprise private registry. The syntax is <optional-hostname>/<namespace>/<module-name>/<provider>. If the hostname is omitted, it defaults to registry.terraform.io. For private registries, prefix the hostname (e.g. app.terraform.io).
The version argument accepts SemVer constraints (~>, >=, =, etc.). terraform init -upgrade updates to the latest version within the constraint, while init without -upgrade respects the existing cache. Authentication is typically handled by token management via terraform login.
Fetched from a Git repository. Prefix the source with git:: and use either HTTPS or SSH. To target a subdirectory inside the repo, append //path/to/module. To pin the version, use ?ref=tag|branch|sha.
For authentication, prepare an HTTPS personal access token, or an SSH deploy key / SSH agent. In CI, the practical baseline is to inject credentials via environment variables or an auth agent — never hardcode them into the URL.
Reference a module that exists in the same repository or on the local filesystem via a relative or absolute path. There is no fetch step — the module is referenced in place. Relative paths are resolved from the root module.
Changes are picked up immediately, but there is no version-pinning concept — reproducibility comes from branch workflows and release processes. Local sources don't scale to reuse across repositories; for that, promote to git or registry distribution.
Choose based on two criteria: reproducibility guarantees and ease of distribution. Registry is best for stable distribution across teams and organizations; git fits the development phase and internal sharing; local fits fast iteration inside a single repository.
| Source Type | Syntax Example | Version Pinning | Subdirectory Specification |
|---|---|---|---|
| Registry (public/private) | hashicorp/consul/aws, app.terraform.io/acme/network/aws | SemVer constraints such as version = "~> 1.2" | Not needed (modules are distributed as units) |
| Git | git::https://github.com/acme/infra.git//modules/vpc?ref=v1.2.0 | ?ref= tag/branch/commit | Append //path/to/module |
| Local Path | ./modules/network, ../shared/vpc | Not supported (rely on repository workflow) | Reach via the path itself (no special notation) |
The three frequently tested pillars are: "version is registry-only", "for git, // means subdirectory and ?ref= means pinning", and "local sources are referenced directly without being fetched". Also nail down the meaning of init vs init -upgrade, the risk of omitting ref, and the hostname prefix for private registries.
Below are minimal examples of all three forms. Compare the syntax and pinning mechanism for each.
Minimal example of the three module source forms
module "net_registry" {
source = "app.terraform.io/acme/network/aws"
version = "~> 1.2"
cidr = "10.0.0.0/16"
}
module "net_git" {
source = "git::https://github.com/acme/infra-mods.git//modules/network?ref=v1.2.3"
cidr = "10.1.0.0/16"
}
module "net_local" {
source = "./modules/network"
cidr = "10.2.0.0/16"
}Associate
問題 1
Which is the correct syntax to reference the modules/network subdirectory of a Git repository, pinned to tag v1.2.3?
正解: A
Git sources require the git:: prefix, use //path for subdirectories, and pin via ?ref=tag|branch|sha. The version argument is registry-only, and #tag is not supported.
Can I use the version argument with git or local sources?
No. The version argument is registry-only. With git you pin via ?ref= (tag, branch, or commit), and with local you rely on repository workflow and release procedures for reproducibility.
How do I reference a module from a Terraform Cloud private registry?
Include the hostname in source, e.g. app.terraform.io/<organization>/<name>/<provider>. Run terraform login first to acquire a CLI token used for authentication during init.
How do I safely access private Git modules from CI?
Inject read-only SSH deploy keys or HTTPS personal access tokens via environment variables or an auth agent. The practical rules: never hardcode credentials in the URL, and always pin with ref to guarantee reproducibility.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
HCL Syntax: Terraform's Configuration Language (2026)
HCL2 fundamentals for Terraform — blocks, attributes, expres...
Terraform Authoring & Operations Pro: Complete Guide (2026)
Tactics for the Terraform Pro exam — module authoring, works...
Terraform Providers: Plugin Management Fundamentals (2026)
Provider mechanics — required_providers, versions, mirrors, ...
Terraform Resource Blocks: Declarative Infra Units (2026)
Resource block fundamentals — addresses, references, common ...
Terraform Data Sources: Read-Only External Data (2026)
Data source basics — declaration, refresh behavior, dependen...