Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

JINIers

220901_Interact with Terraform Modules 본문

GCP/Qwiklabs

220901_Interact with Terraform Modules

JINIers 2022. 9. 1. 13:57

Terraform 모듈과 상호 작용

 

[개요]

terrform으로 인프라를 관리하면 복잡한 구성이 생성됨
그럴 때 발생하는 문제
1. 구성파일을 이해하고 탐색하기 어려움
2. 한 블록을 업데이트 하면 구성의 다른 블록에 의도하지 않은 결과가 발생할 수 있으므로 구성 업데이트는 더 위험해짐
3. 프로젝트와 팀 간에 구성의 일부를 공유하려는 경우 프로젝트 간 구성블록을 복붙하는 것은 오류가 발생하기 쉽고 유지 관리하기 어려울 수 있음

▶ 모듈을 사용하면 위의 문제들을 해결할 수 있음

- Organize configuration
구성의 관련부분을 함께 유지하여 구성을 보다 쉽개 탐색, 이해 및 업데이트 할 수 있다.
모듈을 사용하여 구성을 논리적 수엉요소로 구성할 수 있음

- Encapsulate configuration(구성 캡슐화)
구성의 한 부분이 변경되어 우발적으로 다른 인프라가 변경되는 것과 같은 의도하지않은 결과를 방지함
또 두 개의 다른 리소스에 동일한 이름을 사용하느 ㄴ것과 같은 단순한 오류의 가능성을 줄일 수 있음

- Re-use configuration(구성 재사용)
기존코드를 사용하지 않고 모든 구성을 작성하면 시간이 많이 걸리고 오류가 발생하기 쉬움
모듈을 사용하면 나 / 팀원 / 사용할 모듈을 게시한 다른 테라폼 실무자 / 가 작성한 구성을 재사용하여 시간을 절약하고 비용이 많이 드는 오류를 줄일 수 있음

- Provide consistency and ensure best practices
구성의 일관성을 제공하는데 도움이 됨
일관성을 통해 복잡한 구성을 더 쉽게 이해할 수 있으며 모범 사례를 모든 구성에 적용할 수 있음

 


[terrform 모듈이란?]

단일 디렉토리에 있는 terrform 구성파일세트


모듈 구성

$ tree minimal-module/
.
├── LICENSE
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf

작업 1. 레지스트리의 모듈 사용

[terrform 구성만들기: git에서 예제프로젝트 복제]

git clone https://github.com/terraform-google-modules/terraform-google-network
cd terraform-google-network
git checkout tags/v3.3.0 -b v3.3.0


[terraform-google-network/examples/simple_project 의 main.tf 확인]

cd terraform-google-network/examples/simple_project

vi main.tf

경로

경로
경로 내의 main.tf

 


[루트 입력변수 정의]

프로젝트 id 검색

gcloud config list --format 'value(core.project)'

 

 

[변수 설정]

vi variables.tf

내용추가

variable "project_id" {
  description = "The project ID to host the network in"
  default     = "프로젝트 id 입력"
}

variable "network_name" {
  description = "The name of the VPC network being created"
  default     = "example-vpc"
}

동일경로 내의 variables.tf

를 아래와 같이 수정


[루트 출력값 정의]

vi outputs.tf

동일경로 내의 output.tf

 


[인프라 프로비저닝]

 

simple_project로 이동

cd ~/terraform-google-network/examples/simple_project

 

구성 초기화

terraform init

 

vpc 생성

terraform apply
yes

 

[인프라 정리]

terraform destroy
yes

 


작업 2. 모듈 빌드

대충 이렇게

[모듈만들기]

새 모듈의 디렉터리 만들기

cd ~
touch main.tf
mkdir -p modules/gcs-static-website-bucket



모듈 디렉토리 이동, 빈 파일 만들기

cd modules/gcs-static-website-bucket
touch website.tf variables.tf outputs.tf


README.md 에 gcs-static-website-bucket 만들기

vi README.md

내용

# GCS static website bucket
This module provisions Cloud Storage buckets configured for static website hosting.


LICENSE 파일 생성

vi LICENSE

내용

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


이쯤되면 현재 모듈 디렉터리 구조가 이래야함

main.tf
modules/
└── gcs-static-website-bucket
    ├── LICENSE
    ├── README.md
    ├── website.tf
    ├── outputs.tf
    └── variables.tf

 


website.tf 에 내용 추가

vi website.tf

내용

resource "google_storage_bucket" "bucket" {
  name               = var.name
  project            = var.project_id
  location           = var.location
  storage_class      = var.storage_class
  labels             = var.labels
  force_destroy      = var.force_destroy
  uniform_bucket_level_access = true
  versioning {
    enabled = var.versioning
  }
  dynamic "retention_policy" {
    for_each = var.retention_policy == null ? [] : [var.retention_policy]
    content {
      is_locked        = var.retention_policy.is_locked
      retention_period = var.retention_policy.retention_period
    }
  }
  dynamic "encryption" {
    for_each = var.encryption == null ? [] : [var.encryption]
    content {
      default_kms_key_name = var.encryption.default_kms_key_name
    }
  }
  dynamic "lifecycle_rule" {
    for_each = var.lifecycle_rules
    content {
      action {
        type          = lifecycle_rule.value.action.type
        storage_class = lookup(lifecycle_rule.value.action, "storage_class", null)
      }
      condition {
        age                   = lookup(lifecycle_rule.value.condition, "age", null)
        created_before        = lookup(lifecycle_rule.value.condition, "created_before", null)
        with_state            = lookup(lifecycle_rule.value.condition, "with_state", null)
        matches_storage_class = lookup(lifecycle_rule.value.condition, "matches_storage_class", null)
        num_newer_versions    = lookup(lifecycle_rule.value.condition, "num_newer_versions", null)
      }
    }
  }
}



variables.tf에 내용 추가

vi variables.tf

내용입력

variable "name" {
  description = "The name of the bucket."
  type        = string
}
variable "project_id" {
  description = "The ID of the project to create the bucket in."
  type        = string
}
variable "location" {
  description = "The location of the bucket."
  type        = string
}
variable "storage_class" {
  description = "The Storage Class of the new bucket."
  type        = string
  default     = null
}
variable "labels" {
  description = "A set of key/value label pairs to assign to the bucket."
  type        = map(string)
  default     = null
}
variable "bucket_policy_only" {
  description = "Enables Bucket Policy Only access to a bucket."
  type        = bool
  default     = true
}
variable "versioning" {
  description = "While set to true, versioning is fully enabled for this bucket."
  type        = bool
  default     = true
}
variable "force_destroy" {
  description = "When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."
  type        = bool
  default     = true
}
variable "iam_members" {
  description = "The list of IAM members to grant permissions on the bucket."
  type = list(object({
    role   = string
    member = string
  }))
  default = []
}
variable "retention_policy" {
  description = "Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."
  type = object({
    is_locked        = bool
    retention_period = number
  })
  default = null
}
variable "encryption" {
  description = "A Cloud KMS key that will be used to encrypt objects inserted into this bucket"
  type = object({
    default_kms_key_name = string
  })
  default = null
}
variable "lifecycle_rules" {
  description = "The bucket's Lifecycle Rules configuration."
  type = list(object({
    # Object with keys:
    # - type - The type of the action of this Lifecycle Rule. Supported values: Delete and SetStorageClass.
    # - storage_class - (Required if action type is SetStorageClass) The target Storage Class of objects affected by this Lifecycle Rule.
    action = any
    # Object with keys:
    # - age - (Optional) Minimum age of an object in days to satisfy this condition.
    # - created_before - (Optional) Creation date of an object in RFC 3339 (e.g. 2017-06-13) to satisfy this condition.
    # - with_state - (Optional) Match to live and/or archived objects. Supported values include: "LIVE", "ARCHIVED", "ANY".
    # - matches_storage_class - (Optional) Storage Class of objects to satisfy this condition. Supported values include: MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, DURABLE_REDUCED_AVAILABILITY.
    # - num_newer_versions - (Optional) Relevant only for versioned objects. The number of newer versions of an object to satisfy this condition.
    condition = any
  }))
  default = []
}



outputs.tf에 모듈 출력 추가

vi outputs.tf

내용입력

output "bucket" {
  description = "The created storage bucket"
  value       = google_storage_bucket.bucket
}



main.tf에 새 모듈에 대한 참조 추가

cd ~
vi main.tf

내용입력

module "gcs-static-website-bucket" {
  source = "./modules/gcs-static-website-bucket"
  name       = var.name
  project_id = var.project_id
  location   = "us-east1"
  lifecycle_rules = [{
    action = {
      type = "Delete"
    }
    condition = {
      age        = 365
      with_state = "ANY"
    }
  }]
}


홈 디렉토리에 outputs.tf파일 생성

cd ~
touch outputs.tf


outputs.tf 코드추가

output "bucket-name" {
  description = "Bucket names."
  value       = "module.gcs-static-website-bucket.bucket"
}


홈 디렉토리에 variables.tf 생성

touch variables.tf


variables.tf 코드추가

variable "project_id" {
  description = "The ID of the project in which to provision resources."
  type        = string
  default     = "프로젝트 ID 입력해"
}
variable "name" {
  description = "Name of the buckets to create."
  type        = string
  default     = "버킷이름 입력해"
}


[로컬모듈 설치]

초기화

terraform init

적용

terraform apply
yes

 


[버킷에 파일 업로드]

샘플 콘텐츠 다운로드

cd ~
curl https://raw.githubusercontent.com/hashicorp/learn-terraform-modules/master/modules/aws-s3-static-website-bucket/www/index.html > index.html
curl https://raw.githubusercontent.com/hashicorp/learn-terraform-modules/blob/master/modules/aws-s3-static-website-bucket/www/error.html > error.html



파일 버킷에 복사

gsutil cp *.html gs://버킷이름넣어

버킷 생성 완




[웹 사이트 및 인프라 정리]

terraform destroy

 

Comments