모듈 인터페이스를 통한 리소스 라벨 지정을 유연하게 수행합니다.
다음과 같이 빈 맵의 기본값을 labels 변수에 제공합니다.
variable"labels"{description="A map of labels to apply to contained resources."default={}type="map"}
모든 리소스에 대해 출력 노출
변수 및 출력을 사용해서 모듈과 리소스 사이의 종속 항목을 유추할 수 있습니다.
출력이 없으면 해당 Terraform 구성과 관련해서 사용자가 모듈을 올바르게 주문할 수 없습니다.
공유 모듈에 정의된 모든 리소스에 대해 리소스를 참조하는 출력을 하나 이상 포함합니다.
복잡한 논리에 인라인 하위 모듈 사용
인라인 모듈을 사용하여 복잡한 Terraform 모듈을 더 작고 중복성이 제거된 공통 리소스로 관리할 수 있습니다.
modules/$modulename에 인라인 모듈을 둡니다.
공유 모델 문서에 특별히 기술되어 있지 않은 한 인라인 모듈을 외부 모듈에 사용되지 않는 비공개 모듈로 취급합니다.
Terraform은 리팩터링된 리소스를 추적하지 않습니다. 최상위 모듈에서 일부 리소스로 시작하고 이를 하위 모듈에 푸시하면 Terraform이 모든 리팩터링된 리소스를 다시 만들려고 시도합니다. 이러한 동작을 해결하기 위해서는 리팩터링할 때 moved 블록을 사용합니다.
내부 모듈에 정의된 출력은 자동으로 노출되지 않습니다. 내부 모듈의 출력을 공유하려면 이를 다시 내보냅니다.
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["이해하기 어려움","hardToUnderstand","thumb-down"],["잘못된 정보 또는 샘플 코드","incorrectInformationOrSampleCode","thumb-down"],["필요한 정보/샘플이 없음","missingTheInformationSamplesINeed","thumb-down"],["번역 문제","translationIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-09-04(UTC)"],[[["\u003cp\u003eReusable Terraform modules should include API activation with an \u003ccode\u003eenable_apis\u003c/code\u003e variable to disable it, and must set \u003ccode\u003edisable_services_on_destroy\u003c/code\u003e to \u003ccode\u003efalse\u003c/code\u003e to avoid conflicts.\u003c/p\u003e\n"],["\u003cp\u003eShared modules must contain an \u003ccode\u003eOWNERS\u003c/code\u003e or \u003ccode\u003eCODEOWNERS\u003c/code\u003e file to document who is responsible for the module and to require owner approval on pull requests.\u003c/p\u003e\n"],["\u003cp\u003eModules should be versioned according to SemVer v2.0.0, and users should pin to a major version using a version constraint, such as \u003ccode\u003e~> 20.0\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eShared modules should not configure providers or backends, but should define minimum required provider versions in a \u003ccode\u003erequired_providers\u003c/code\u003e block in order to let the root module handle it.\u003c/p\u003e\n"],["\u003cp\u003eEvery resource within a shared module should have at least one corresponding output to allow users to infer dependencies and properly order their Terraform configurations.\u003c/p\u003e\n"]]],[],null,["# Best practices for reusable modules\n\nThis document provides guidelines and recommendations to consider when using\nreusable Terraform modules.\n\nThis guide is not an introduction to Terraform. For an introduction to using\nTerraform with Google Cloud, see\n[Get started with Terraform](/docs/terraform/get-started-with-terraform).\n\nActivate required APIs in modules\n---------------------------------\n\nTerraform modules can activate any required services by using the\n`google_project_service` resource or the\n[`project_services`](https://github.com/terraform-google-modules/terraform-google-project-factory/tree/master/modules/project_services) module.\nIncluding API activation makes demonstrations easier.\n\n- If API activation is included in a module, then the API activation *must* be disableable by exposing an `enable_apis` variable that defaults to `true`.\n- If API activation is included in a module, then the API activation *must*\n set `disable_services_on_destroy` to `false`, because this attribute can\n cause issues when working with multiple instances of the module.\n\n For example: \n\n module \"project-services\" {\n source = \"terraform-google-modules/project-factory/google//modules/project_services\"\n version = \"~\u003e 12.0\"\n\n project_id = var.project_id\n enable_apis = var.enable_apis\n\n activate_apis = [\n \"compute.googleapis.com\",\n \"pubsub.googleapis.com\",\n ]\n disable_services_on_destroy = false\n }\n\nInclude an owners file\n----------------------\n\nFor all shared modules, include an\n[`OWNERS`](https://github.com/bkeepers/OWNERS)\nfile (or\n[`CODEOWNERS`](https://blog.github.com/2017-07-06-introducing-code-owners/)\non GitHub), documenting who is responsible for the module. Before any pull\nrequest is merged, an owner should approve it.\n\n### Release tagged versions\n\nSometimes modules require breaking changes and you need to communicate the\neffects to users so that they can pin their configurations to a specific\nversion.\n\nMake sure that shared modules follow\n[SemVer v2.0.0](https://semver.org/spec/v2.0.0.html)\nwhen new versions are tagged or released.\n\nWhen referencing a module, use a\n[version constraint](https://www.terraform.io/language/expressions/version-constraints)\nto pin to the *major* version. For example: \n\n module \"gke\" {\n source = \"terraform-google-modules/kubernetes-engine/google\"\n version = \"~\u003e 20.0\"\n }\n\nDon't configure providers or backends\n-------------------------------------\n\nShared modules [must not configure providers or backends](https://developer.hashicorp.com/terraform/language/providers/configuration#provider-configuration-1).\nInstead, configure providers and backends in root modules.\n\nFor shared modules, define the minimum required provider versions in a\n[`required_providers`](https://www.terraform.io/language/modules/develop/providers#provider-version-constraints-in-modules)\nblock, as follows: \n\n terraform {\n required_providers {\n google = {\n source = \"hashicorp/google\"\n version = \"\u003e= 4.0.0\"\n }\n }\n }\n\nUnless proven otherwise, assume that new provider versions will work.\n\nExpose labels as a variable\n---------------------------\n\nAllow flexibility in the labeling of resources through the module's interface.\nConsider providing a `labels` variable with a default value of an empty map, as\nfollows: \n\n variable \"labels\" {\n description = \"A map of labels to apply to contained resources.\"\n default = {}\n type = \"map\"\n }\n\nExpose outputs for all resources\n--------------------------------\n\nVariables and outputs let you infer dependencies between modules and resources.\nWithout any outputs, users cannot properly order your module in relation to\ntheir Terraform configurations.\n\nFor every resource defined in a shared module, include at least one output that\nreferences the resource.\n\nUse inline submodules for complex logic\n---------------------------------------\n\n- Inline modules let you organize complex Terraform modules into smaller units and de-duplicate common resources.\n- Place inline modules in `modules/$modulename`.\n- Treat inline modules as private, not to be used by outside modules, unless the shared module's documentation specifically states otherwise.\n- Terraform doesn't track refactored resources. If you start with several resources in the top-level module and then push them into submodules, Terraform tries to recreate all refactored resources. To mitigate this behavior, use [`moved`](https://www.terraform.io/language/modules/develop/refactoring#moved-block-syntax) blocks when refactoring.\n- Outputs defined by internal modules aren't automatically exposed. To share outputs from internal modules, re-export them.\n\nWhat's next\n-----------\n\n- Learn about [general style and structure best practices for Terraform on Google Cloud](/docs/terraform/best-practices/general-style-structure).\n- Learn about [best practices when using Terraform root modules](/docs/terraform/best-practices/root-modules)."]]