brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Oct 14. 2022

3. 테라폼-GCP-모듈

테라폼 사용 시

한 블록을 업데이트해서 다른 블록에 영향을 주지 않도록 필요함.

개발, 스테이징, 프로덕션 구성시 중복 증가할 수 있어, 업데이트 시 문제가 될 수 있다.


모듈 호출할 수 있다.

유용한 모듈 찾는 곳  https://registry.terraform.io/

예 ) AWS VPC 모듈   https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest



<1> 기본 정보 확인

<2> 소스 받기

<3>  변수 값 입력 

<4>  아웃풋 파일

<5>  모듈 만들기




<1> 기본 정보 확인


gcloud auth list

승인


gcloud config list project




<2> 소스 받기



모듈 소스 목록

https://www.terraform.io/language/modules/sources


네트워크 모듈 https://registry.terraform.io/modules/terraform-google-modules/network/google/3.3.0


1

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

cd examples/simple_project


2

프로젝트 id 확인하기

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



3

$ vi main.tf


provider "google" {

  version = "~> 3.45.0"

}


provider "null" {

  version = "~> 2.1"

}


# [START vpc_custom_create]

module "test-vpc-module" {

  source       = "terraform-google-modules/network/google"

  version      = "~> 3.2.0"

  project_id   = var.project_id # Replace this with your project ID in quotes

  network_name = "my-custom-mode-network"

  mtu          = 1460


  subnets = [

    {

      subnet_name   = "subnet-01"

      subnet_ip     = "10.10.10.0/24"

      subnet_region = "us-west1"

    },

    {

      subnet_name           = "subnet-02"

      subnet_ip             = "10.10.20.0/24"

      subnet_region         = "us-west1"

      subnet_private_access = "true"

      subnet_flow_logs      = "true"

    },

    {

      subnet_name               = "subnet-03"

      subnet_ip                 = "10.10.30.0/24"

      subnet_region             = "us-west1"

      subnet_flow_logs          = "true"

      subnet_flow_logs_interval = "INTERVAL_10_MIN"

      subnet_flow_logs_sampling = 0.7

      subnet_flow_logs_metadata = "INCLUDE_ALL_METADATA"

    }

  ]

}




//  설명

network_name = "my-custom-mode-network"

provider  google

locals  3 subnet

module test-vpc-module




<3>  변수 값 입력 


1

project id  확인?

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



2

variables.tf.


variable "project_id" {

  description = "The project ID to host the network in"

  default     = "seismic-catbird-358207"

}


variable "network_name" {

  description = "The name of the VPC network being created"

  default     = "tts-vpc"

}





<4>  아웃풋 파일


1

output.tf


output "network_name" {

  value       = module.test-vpc-module.network_name

  description = "The name of the VPC being created"

}

output "network_self_link" {

  value       = module.test-vpc-module.network_self_link

  description = "The URI of the VPC being created"

}

output "project_id" {

  value       = module.test-vpc-module.project_id

  description = "VPC project id"

}

output "subnets_names" {

  value       = module.test-vpc-module.subnets_names

  description = "The names of the subnets being created"

}

output "subnets_ips" {

  value       = module.test-vpc-module.subnets_ips

  description = "The IP and cidrs of the subnets being created"

}

output "subnets_regions" {

  value       = module.test-vpc-module.subnets_regions

  description = "The region where subnets will be created"

}

output "subnets_private_access" {

  value       = module.test-vpc-module.subnets_private_access

  description = "Whether the subnets will have access to Google API's without a public IP"

}

output "subnets_flow_logs" {

  value       = module.test-vpc-module.subnets_flow_logs

  description = "Whether the subnets will have VPC flow logs enabled"

}

output "subnets_secondary_ranges" {

  value       = module.test-vpc-module.subnets_secondary_ranges

  description = "The secondary ranges associated with these subnets"

}

output "route_names" {

  value       = module.test-vpc-module.route_names

  description = "The routes associated with this VPC"

}






<5> 만들기



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


초기화

terraform init


terraform apply

Enter a value: yes


module.test-vpc-module.module.vpc.google_compute_network.network: Creating...

module.test-vpc-module.module.vpc.google_compute_network.network: Still creating... [10s elapsed]

module.test-vpc-module.module.vpc.google_compute_network.network: Creation complete after 12s [id=projects/seismic-catbird-358207/global/networks/my-custom-mode-network]

module.test-vpc-module.module.subnets.google_compute_subnetwork.subnetwork["us-west1/subnet-01"]: Creating...


Outputs:


network_name = "my-custom-mode-network"

network_self_link = "https://www.googleapis.com/compute/v1/projects/seismic-catbird-358207/global/networks/my-custom-mode-network"

project_id = "seismic-catbird-358207"

route_names = []

subnets_flow_logs = [

  false,

  true,

  true,

]

subnets_ips = [

  "10.10.10.0/24",

  "10.10.20.0/24",

  "10.10.30.0/24",

]

subnets_names = [

  "subnet-01",

  "subnet-02",

  "subnet-03",

]

subnets_private_access = [

  false,

  true,

  false,

]

subnets_regions = [

  "us-west1",

  "us-west1",

  "us-west1",

]

subnets_secondary_ranges = [

  tolist([]),

  tolist([]),

  tolist([]),

]





2

콘솔에서  vpc 확인




3

삭제


terraform destroy

엔터

엔터

yes


디폴트 네트워크만 남는다.




<6>  모듈 만들기


1

정적 웹사이트를 호스팅 하는 데 사용되는  스토리지 버킷을 관리하는 모듈을 생성한다.


모듈을 만들고 루트에서 가져다 쓴다.


루트 파일

main.tf

variables.tf

outputs.tf


terraform.tfstate    ,  terraform.tfstate.backup  파일에 상태가 포함되어 있다.



2

디렉토리 구조?


main.tf

modules --------gcs-static-website-bucket ------- website.tf / output.tf / variable.tf




3

모듈 만들기.


cd ~

touch main.tf

mkdir -p modules/gcs-static-website-bucket


4

cd modules/gcs-static-website-bucket

touch website.tf variables.tf outputs.tf



tee -a README.md <<EOF

 bucket - static website hosting.

EOF




5

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)

      }

    }

  }

}





6

modules  디렉토리로 이동  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 = []

}





7

출력

 output.tf   모듈 내부의 파일에서 모듈을 출력한다.


output "bucket" {

  description = "The created storage bucket"

  value       = google_storage_bucket.bucket

}




8

루트에서

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"

    }

  }]

}




9

루트에서

cd ~

touch outputs.tf


output "bucket-name" {

  description = "Bucket names."

  value       = "module.gcs-static-website-bucket.bucket"

}




10

루트에서

touch variables.tf


variable "project_id" {

  description = "The ID of the project in which to provision resources."

  type        = string

  default     = "FILL IN YOUR PROJECT ID HERE"

}

variable "name" {

  description = "Name of the buckets to create."

  type        = string

  default     = "FILL IN A (UNIQUE) BUCKET NAME HERE"

}



11

terraform init

terraform apply




12

샘플 다운로드 , 업로드

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://YOUR-BUCKET-NAME


버킷에 파일 업로드.

정적 웹 사이트를 만들었다.




13

terraform destroy





https://brunch.co.kr/@topasvga/2419


감사합니다.

매거진의 이전글 2. 테라폼 -GCP-네트워크,서버 추가,정보 변경
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari