0%

AWS_VPC-LAB1_By-Terraform

AWS_VPC-LAB1 By Terraform

本篇主要是利用時下流行基礎架構程式 (IaC)工具: Terraform 重新部署上一篇AWS_VPC-LAB1 內容。以下步驟與上一篇一樣

  • 建立VPC (Virtual Private Cloud)
  • 建立IGW (Internet Gateway)
  • 建立Subnet
  • 建立Routing Table
  • 將路由表與Subnet建立關聯
  • 建立Security Group
  • 獲取AMI
  • 建立EC2
  • 執行 Terraform
  • 測試
  • 清理Lab所建立的所有元件

完整部署後,如下圖所示:

AWS_VPC-Public

開始部署之前

本篇不是Terraform 基礎教學,若不清楚Terraform可以看參考資料。

  • 安裝Terraform 很簡單可以看官網-Install Terraform

  • 使用AWS API之前都需要先到IAM 設定申請一組keySECRET_ACCESS_KEY

    因為只是LAB,為了方便執行通常都會將申請好的key放置在shell script

    myauth_key.sh

    1
    2
    3
    #!/bin/bash
    export AWS_ACCESS_KEY_ID='your key id'
    export AWS_SECRET_ACCESS_KEY='your secret key'

    在執行任何AWS API或Terraform之前先執行 myauth_key.sh

    1
    source ./myhome-auth_key.sh
  • 完整Terraform Hcl code 在此88gocode/AWS-LAB-Terraform

    1
    2
    3
    git clone https://github.com/88gocode/AWS-LAB-Terraform.git
    cd AWS-LAB-Terraform
    git checkout lab1

    先宣告變數

    以下開始是Terraform hcl 語法。此節將VPC , subnet 等需要網段及登入 EC2 需要Key的名稱等參數, 用變數方式載入便於其他資源物件利用。

vars.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
variable "AWS_REGION" {
default = "ap-northeast-3"
}
variable "AWS_AZ" {
default = "ap-northeast-3a"
}
variable "vpc_cidr_lab0" {
default = "10.1.0.0/16"
description = "the vpc cidr"
}
variable "public_subnet_cidr_lab0" {
default = "10.1.1.0/24"
description = "The cidr of the public subnet"
}
variable "key_name" {
default = "my-test"
}

佈建雲端 IaaS 使用Terraform 好處是它提供多樣Provider : 像是 AWS,GCP,Azure,aliyun,DigitalOcean等等
以下是宣告是使用AWS Provider
provider.tf

1
2
3
4
provider "aws" {
profile = "default"
region = var.AWS_REGION
}

建立VPC(Virtual Private Cloud)

vpc.tf

1
2
3
4
5
6
7
8
9
10
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr_lab0
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
enable_classiclink = "false"
tags = {
Name = "main-simple_VPC"
}
}

建立 igw

接續上一節 vpc.tf 內容 , 這邊只是列出建立 igw 的內容

vpc.tf

1
2
3
4
5
6
7
8
# igw
resource "aws_internet_gateway" "main-igw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"

}
}

建立Subnet

subnet.tf

1
2
3
4
5
6
7
8
9
10
# Create Publi Subnet
resource "aws_subnet" "az1-public1-subnet" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr_lab0
availability_zone = var.AWS_AZ
map_public_ip_on_launch = "true"
tags = {
Name = "main-az1-public1-sunet"
}
}

建立Routing Table

route.tf

1
2
3
4
5
6
7
8
9
10
11
# Create Route Table
resource "aws_route_table" "main-public-rt" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-public-rt"
}
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main-igw.id
}
}

將路由表與Subnet建立關聯

同樣地,接續上一節 route.tf內容,將已建立的Subnet,Routing Table等物件兩者做個關聯。

route.tf

1
2
3
4
5
# route associations public
resource "aws_route_table_association" "main-public-rt-az1" {
subnet_id = aws_subnet.az1-public1-subnet.id
route_table_id = aws_route_table.main-public-rt.id
}

建立Security Group(SG)

建立SG 名為 AZ1_Pub_sg1,新增兩筆傳入規則

  • 任何來源 0.0.0.0/0 ,tcp port 22 都允許
  • 任何來源 0.0.0.0/0 ,ICMP-IPv4

sg.tf

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
resource "aws_security_group" "sg" {
name = "main_sg1"
vpc_id = aws_vpc.main.id

ingress {
from_port = "22"
to_port = "22"
protocol = "TCP"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
from_port = "-1"
to_port = "-1"
protocol = "ICMP"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
Name = "main_sg1"
}
}

AWS的 SG 是屬於StateFul,都是綁定在ENI(Elastic Network Interface: 網卡)上(相當於Linux Iptable角色);NACL 屬於 Stateless,都是綁定上 Subnet

獲取AMI

使用Terraform 核心組件 Data source(若對Terraform 基礎觀念不了解的,可以看參考資料的介紹)來找尋適合 EC2 AMI

以下找尋AMI 條件

  • amazon自己發行的

  • AMI 名稱開頭為 “^amzn.*”

  • VM-type : hvm

  • root-device-type: abs

  • 最近發行的AMI

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
data "aws_ami"  "example" {
most_recent = true
owners = ["amazon"]
name_regex = "^amzn.*"

filter {
name = "virtualization-type"
values = ["hvm"]

}
filter {
name = "root-device-type"
values = ["ebs"]
}
}

output "ami_id" {
value = data.aws_ami.example.id
description = "demo for AMI Image ID"
}

output "IP" {
value = aws_instance.example.public_ip
description = "Public IP for demo"
}

建立EC2

這邊EC2簡單建立, 將已建好Subnet ,Security Group (sg) ,及透過data source 獲取AMI ID
ec2.tf

1
2
3
4
5
6
7
8
9
10
11
12
resource "aws_instance" "example" {
ami = data.aws_ami.example.id
instance_type = "t2.micro"
# the VPC subnet
subnet_id = aws_subnet.az1-public1-subnet.id

# the security group
vpc_security_group_ids = [aws_security_group.sg.id]

# the public SSH key
key_name = var.key_name
}

執行 Terraform

完整目錄架構如下:

1
2
3
4
5
6
7
8
9
.
├── ec2.tf
├── myDatasource.tf
├── provider.tf
├── route.tf
├── sg.tf
├── subnet.tf
├── vars.tf
└── vpc.tf

第一次執行Terraform,需要初始化先下載對應的Provider (本篇是 AWS),完成後,於所在目錄底下有一個隱藏檔 .terraform

1
terraform init

可以查看剛寫的 terraform 語法是否正確

1
terraform validate

執行測試計畫,可以看所列的參數

1
terraform plan

開始部署

1
terraform apply  -auto-approve

測試

  • 透過public ip 使用 ssh 加上 key 的方式連進來
  • 在EC2 上聯外

執行完terraform後,會出現以下內容; 如圖

測試 連進 EC2

1
ssh -i my-test.pem [email protected]

清理

AWS 的價值貴於方便與彈性,使用多少算多少錢,因此這個只是個LAB ,不用時記得將他清理刪除。
使用Terraform 只要下以下指令即可清理完成。

1
terraform destroy

參考資料

歡迎關注我的其它發布渠道