DevOps課程-IaC with Terraform 12

Automate Provisioning EC2 with Terraform — Part1

ZONGRU Li
11 min readFeb 16, 2022

前面篇章學完了:

  1. Terraform Configuration File
  2. Terraform Syntax:
  • Resources
  • Data Sources
  • Variables

並且我這邊將前面由Terraform製作的InfraStructure都做destroy

接下來要實際建立真實可能會使用的Resource — AWS EC2

考慮的場景將是可以運行nginx Docker container

但是在建立EC2 instance之前,要先建立整個背後支撐的InfraStructure

需要的InfraStructure Resources與建置順序有(Resources如粗體字):

  1. VPC(額外建立,而不使用到Default給的VPC環境)
  2. 在上述VPC內建立Subnet

(雖然可以在多個availability zone內建N個Subnet,但是這邊就建一個就好)

3. Route table & Internet Gateway(為了讓外面可以連進去nginx)

4. provision EC2 instance

5. 然後佈署nginx的Docker container

6. 建立Security Group(firewall)

實際概念圖如下:

InfraStructure建立示意圖

VPC與Subnet建置:

實際改造當前專案內容:

main.tf檔內調整為:

本機變數檔檔名改為Terraform能吃到的"terraform.tfvars":

執行前確認狀態AWS:

執行plan指令比對跟Code的狀態:

#執行比Terraform對指令:
terraform plan

如上會有兩個InfraStructureResources物件會依據Code建立出來

確認沒有問題就執行apply指令:

#執行Terraform apply指令:
terraform apply --auto-aprove

此時前面提到的1 & 2 Resources就建立完成了!

再來是建立第三項建置:

Route table & Internet Gateway(為了讓外面可以連進去nginx)

但是首先看到的是:

如上圖,Route tableNetwork ACLVPC建立時就會自動帶出來了

其中Route table是每個VPC必要的Resource

Network ACL則是基於subnet建立出來的

a.首先來看到這個Network ACL:

其實Network ACL簡單來說就是Subnet的防火牆設置

(相對於以前設置的Security Group 對應到(EC2)Server,只是預設是關閉的)

(之於NACL(NetworkACL)對應到Subnet的關係,只是預設是打開的)

b.再來看到上面提到的Route table(在vpc頁面點進去):

下面其實有很多頁籤可以切換,先看到Route(路由):

但是另外看到另一個預設的Route table內容:

主要這些Route(路由)就是控制VPC內部網路的交通

但是可以看到上圖的defaultRoute table

有多一個是針對外部Route(0.0.0.0/0)(而且是針對一個指定gateway)

i.e.在Default的的Route table是有支援與外部網路溝通的

但是由Terraform建立的Route table沒有,也就是如下:

沒有跟外部網路連絡的Route,所以跟外部不通

所以由Terraform建立的VPC,因為缺乏與外部網路連絡的Route

目前不管是外(外部網路)到內(VPC)

或是內(VPC)到外(外部網路)都不可能通

→結論:我們Terraform建的VPC也需要建一個與外部聯絡的Route

然後Terraform也可以用來建立該Route(記得也要連帶建gateway!):

也就是要建如下兩項:

撰寫Terraform Code如下:

完整Code如下:

#執行plan指令確認Code正確性:
terraform plan
#接著執行apply指令:
terraform apply --auto-approve

apply:

AWS網頁上面確認:

點到Route table看到:

點到下面的gateway看到:

AWS的Route table(路由表)特別解說:

再來還會有個問題是剛剛建立的Route table不會跟前面建的Subnet連接

也就是Route table建立出來僅僅是屬於指定的VPC內:

首先我們先回過頭看到AWS預設提供的Route table:

接著另外兩個Route table關係如下兩張圖:

但是只有右邊Custom Route Table有另外對接外部internet gateway(igw):

所以要改成這樣:

<<AWS的Route table(路由表)特別解說 END>>

以上需要改造的"關聯設定"也可以在Terraform Code內設定!

這個"Route table與subnet的關聯設定"也有reosource名稱 :

執行建立:

看到AWS網頁看到自建的Route Table有多一個明確subnet對應:

所以!!!現在只要有EC2 instance建立到這個subnet之內!

這個EC2就能透過上述Route Table對應的igw跟外部溝通

(當然防火牆有開的話)

此時Code如下:

使用預設的建VPC產生的Route Table:

如上所述,這樣我們多出了一個用不到

但是AWS在建立VPC額外配給我們的Route Table

何不乾脆就用這個配給我們的Route Table就好!

所以繼續改造Code:

首先移除剛剛的"aws_route_table_association"

再來註解自己建立的Route Table

然後先apply:

針對AWS在建立VPC提供給我們的預設Route Table也有resource名稱:

aws_default_route_table

但是要提供給它id,其id是在VPC建立的時候會給

#透過以下指令查找default_route_table_id:
terraform state show aws_vpc.myapp-vpc

開始撰寫 →aws_default_route_table:

此時Code如下:

執行plan指令:

確認沒問題,接著執行apply指令:

確認AWS網頁內容:

Security Group建立:

在後面建立EC2 instance之前,我們要先規劃一下網路防火牆的部分

基本上要能夠有22 PORT可以做SSH連線

並且要連到內部Nginx還需要開8080 PORT

這個Security Group是屬於建立的VPC

rule的設置則是ingress(外打內),egress(內打外)

實際resource定義如下:

所以開頭變數還要定義個人電腦IP變數:

實際值要寫到terraform.tfvars檔案內

儲存後先執行plan:

看起來沒有問題,就執行apply:

從AWS網頁上查看:

看到另一個AWS自行建立的resource=>最上面那個sg

點進去Terraform建立的SG裡面卻認定的規則:

傳入(Inbound(ingress)):

傳出(Outbound(egress)):

看起來一切正常

這時候的Code完整如下(main.tf):

另外的變數檔(terraform.tfvars):

但是!!剛剛有看到!!!

AWS因應我們建立的VPC有額外自動建立了defaultSG給我們用了

所以跟上面Route Table依樣,我們也能沿用

沿用Default Security Group:

直接改Code為如下:

執行plan:

確定沒問題,一樣執行apply:

AWS網頁確認結果:

查看這個defaultSG內容:

至此開頭的建置項目:

1,2,3,6都建立完畢了(還差4,5建EC2 instance,安裝docker建Nginx)

當前完整Code如下(main.tf):

terraform.tfvars如下:

另外提醒後面看到建立出來的Resource都不太依樣

因為這個筆記是多天寫成的,有把Resources重建:

不同天撰寫有destroy & apply重建

參考課程reference

--

--

ZONGRU Li
ZONGRU Li

Written by ZONGRU Li

2022/11/17 開源部分個人筆記給LINE "Java程式語言討論區"社群,希望能對社群的技術學習做一點點貢獻.(掩面....記得退訂閱!

No responses yet