iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
DevOps

大家都在用 Terraform 實作 IaC 為什麼不將程式寫得更簡潔易讀呢?系列 第 8

實作 AWS 常用服務之 Terraform 模組系列 - VPC 篇

  • 分享至 

  • xImage
  •  

AWS VPC 模組實作

Virtual Private Cloud (VPC)是 AWS 中的一個虛擬網絡環境,它允許您在 Cloud 中建立和設定自己的網路資源,就像在本地資料中心中設定網路一樣。VPC 提供了隔離、安全和可定制的網路環境,使您能夠在其中運行 AWS 資源,如 EC2 實例、RDS 數據庫等。

本篇是實作常用的 AWS VPC 服務之 Terraform 模組,並且會使用到 YAML 資料結構來定義各自模組的內容。
YAML(YAML Ain't Markup Language)是一種人類可讀且容易寫入的標記語言,它以純文本形式表示資料,並使用縮排(空格或制表符)來表示結構。YAML 通常用於設定文件、資料序列化和資料交換,它的設計目標是提供一種簡潔且易讀的語法,適用於各種程式語言。

本篇是實作常用的 AWS VPC 服務之 Terraform 模組,並且會使用到 YAML 資料結構來定義模組的內容。,完整的專案程式碼分享在我的 Github 上。

  1. 先定義整個專案檔案結構設定檔 ./configs/vpc/my-vpcs.yaml 與模組 my_vpc 的放置位置:
├── configs
│   └── vpc
│       └── my-vpcs.yaml
├── example.tfvars
├── main.tf
├── modules
│   └── my_vpc
│       ├── outputs.tf
│       ├── provider.tf
│       ├── variables.tf
│       └── vpc.tf
└── variables.tf
  1. 撰寫 ./configs/vpc/my-vpcs.yaml 內容來定義 VPC 需要用到的屬性:
  • vpcs: 一個 list 格式來定一多個 vpc 物件
    • vpc_name: VPC 名稱
    • vpc_cidr: VPC CIDR

內容如下:

vpcs:
  - vpc_name: my-vpc
    vpc_cidr: 10.2.0.0/16
  1. 撰寫 my_vpc 模組
  • ./modules/my_vpc/outputs.tf:
output "vpcs" {
  value = aws_vpc.vpcs
}
  • ./modules/my_vpc/provider.tf:
provider "aws" {
    region  = var.aws_region
    profile = var.aws_profile
}
  • ./modules/my_vpc/variables.tf:
    • 變數 vpc_path 為傳入的 my-vpcs.yaml 設定檔路徑位址,透過 yamldecode 取出 key 值 vps 的 value 為一 list 物件
locals {
  vpcs = yamldecode(file("${var.vpc_path}"))["vpcs"]
}

variable "aws_region" {
  description = "AWS region"
  default     = "ap-northeast-1"
}

variable "aws_profile" {
  description = "AWS profile"
  default     = ""
}

variable "project_name" {
  type    = string
  description = "Project name"
  default = ""
}

variable "department_name" {
  type        = string
  description = "Department name"
  default     = "SRE"
}

variable "vpc_path" {
  type        = string
  description = "VPC path"
  default     = ""
}
  • ./modules/my_vpc/vpc.tf:
    利用 for_each 來迭代 locals.vpcsvpc_name 為 key 值建立 map 物件
resource "aws_vpc" "vpcs" {

  for_each = { for r in local.vpcs : r.vpc_name => r }

  assign_generated_ipv6_cidr_block = lookup(each.value, "assign_generated_ipv6_cidr_block", false)
  cidr_block                       = each.value.vpc_cidr
  enable_dns_hostnames             = true
  enable_dns_support               = true
  instance_tenancy                 = "default"

  tags = {
    Department = var.department_name
    Name       = each.value.vpc_name
    Project    = var.project_name
  }

  tags_all = {
    Department = var.department_name
    Name       = each.value.vpc_name
    Project    = var.project_name
  }
}
  1. 撰寫專案相關程式
  • example.tfvars
aws_region="ap-northeast-1"
aws_profile="<YOUR_PROFILE>"
project_name="example"
department_name="SRE"
  • main.tf
terraform {
  required_providers {
    aws = {
      version = "5.15.0"
    }
  }

  backend "s3" {
    bucket                  = "<YOUR_S3_BUCKET_NAME>"
    dynamodb_table          = "<YOUR_DYNAMODB_TABLE_NAME>"
    key                     = "terraform.tfstate"
    region                  = "ap-northeast-1"
    shared_credentials_file = "~/.aws/config"
    profile                 = "<YOUR_PROFILE>"
  }
}

# vpc
module "vpc" {
  aws_profile     = var.aws_profile
  aws_region      = var.aws_region
  department_name = var.department_name
  project_name    = var.project_name
  vpc_path        = "./configs/vpc/my-vpcs.yaml"

  source = "./modules/my_vpc"
}
  • variables.tf
variable "aws_region" {
  type        = string
  description = "AWS Region"
  default     = "ap-northeast-1"
}

variable "aws_profile" {
  type        = string
  description = "Profile in aws/config"
  default     = "nxd-dev"
}

variable "department_name" {
  type    = string
  description = "Department Name"
  default = ""
}

variable "project_name" {
  type    = string
  description = "Project Name"
  default = ""
}

variable "environment" {
  type        = string
  description = "Environment"
  default     = ""
}


Terraform 執行計畫

於專案目錄下執行 terraform init && terraform plan --out .plan -var-file=example.tfvars 來確認一下結果


Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.vpc.aws_vpc.my_vpcs["my-vpc"] will be created
  + resource "aws_vpc" "my_vpcs" {
      + arn                                  = (known after apply)
      + assign_generated_ipv6_cidr_block     = false
      + cidr_block                           = "10.2.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = true
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Department" = "SRE"
          + "Name"       = "my-vpc"
          + "Project"    = "example"
        }
      + tags_all                             = {
          + "Department" = "SRE"
          + "Name"       = "my-vpc"
          + "Project"    = "example"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────

Saved the plan to: .plan

To perform exactly these actions, run the following command to apply:
    terraform apply ".plan"

下一篇將會展示實作 AWS Subnet 之 Terraform 模組。


上一篇
如何利用 HCL 語言的撰寫 Terraform 專案的基本介紹 (Part VII) - 使用 AWS S3 儲存 Terraform State 與 AWS DynamoDB 作為 lock 機制
下一篇
實作 AWS 常用服務之 Terraform 模組系列 - Subnet 篇
系列文
大家都在用 Terraform 實作 IaC 為什麼不將程式寫得更簡潔易讀呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言