2017年9月13日 星期三

透過 AWS Lambda 開發 Serverless Framework(三):使 Lambda 函式擁有 Internet 存取權

Lambda 函式在部署的時候,預設是不會帶有任何網路設定的
因此我們沒辦法知道 Lambda 實際的 IP 位址等等的資訊。
在一些單純的程式中,這可能沒什麼
但如果是在系統的 pipeline 裡,Lambda 需要去存取其他非公開服務時,可能就會有問題了。

舉例來說,可能我有一組內部服務,是僅供內部使用的,因此會透過 AWS 的 security group 限制存取來源。
但是 Lambda 如果想存取這組內部服務,該怎麼辦呢?
我根本不知道 Lambda 執行時的 IP 在哪裡,自然也無法在 security group 上設定允許 Lambda 的 IP。
這時,我們可能就會想要讓 Lambda 被部署在特定的 VPC 內,並且指派 security group 給 Lambda
這樣我就可以在內部服務的 security group 中,允許來自 Lambda 的 security group 的通訊,藉此讓兩邊能連接上。

想像起來好像不是什麼困難的問題,但實際上這會有些連帶的問題產生,也就是 Lambda 掛在 VPC 時,是無法存取網際網路的 [1-2]。
雖然原因我其實還沒想通,不過實際執行時,Lambda 放在具有 Internet Gateway 的 subnet 裡,是無法存取 Internet 的。
如果要讓 Lambda 存取 Internet,一定得透過 NAT Gateway 或者 NAT Instance [3]。

以下就來談談該怎麼設定 VPC,讓 Lambda 能夠存取 Internet。

AWS VPC 設定
選擇 1、使用 VPC Wizard 範本建立 VPC

首先,如果現在手上的 AWS 帳號還沒有做過什麼複雜的設定,也沒什麼既存的東西
那麼最快速建立需要的環境的方法,就是透過 VPC Wizard,並且選擇第二種情境(同時有 Public Subnet 和 Private Subnet)[4]
它可以一口氣幫忙建好整個 VPC 結構,就省得自己 try-and-error 了~XD

選擇 2、手動設定 VPC

不過很不幸地,跟我一樣有既存的網路架構,不能建立一個新的 VPC 就好,那就只好繼續往下看了 XD。

上面的圖是 AWS 的第二種情境 [4] 的架構圖,同時也是這裡想要建立的網路拓樸。
具體來說,在這個 VPC 當中,會有一個 public subnet 和 private subnet
public subnet 用來放其他本身需要直接存取網路的服務,例如 EC2 的 VM 等等的
而 private subnet 則用來放能夠連接網路、但無法被網路連接的服務,像是 Lambda 函式等等。

假設 VPC 本來已經存在的話,通常應該至少有一個 subnet,並且會有一個 routing table
我們就先把既存的 subnet 命名成 Public subnet,而既存的 routing table 則對應為圖中的 custom route table
這是因為既存的網路應該是有接上 Internet Gateway,可以直接存取 Internet 的網路
因此對應到圖上,應該是上半部的 Public subnet 的部份。

在建立 Private subnet 之前,我們要先建立 NAT Gateway
建立時要注意,subnet 的選擇是代表要把這個 NET Gateway 放在哪裡,因此要選擇 Public subnet
(不過如果按照這篇文章的步驟來說,這時我們根本還沒建 Private subnet 就是了 XD)
意思代表著這個 NAT Gateway 的網路閘道,是要通過 Public subnet 的網路閘道(也就是圖中的 igw-id)。

接著,我們必須建立 Private subnet。
首先先新建一個 routing table,命名成 Main route table,以對應圖中右下角的那張 routing table。
然後再新建一個 subnet,命名成 Private subnet。

Private subnet 中需要注意的事項有以下幾點:

  • 在 Route table 頁籤中,記得要把 route table 選擇成 Main route table。

而 Main route table 則需注意:

  • 在 Routes 頁籤中,新增 0.0.0.0/0,Target 要選擇 net-id,也就是前面建立好的 NAT Gateway。
  • 在 Subnet Associations 頁籤中,要把 Private subnet 勾選起來。

這些動作都做好以後,基本上 VPC 就設定完成了!
之後要部署 Lambda 時,就記得要設定 VPC、subnet 和 security group,就可以讓 Lambda 函式存取 Internet 了。
如果是用 serverless 設定的話,就加上下述的欄位。

provider:
    vpc:
        securityGroupIds:
          - sg-xxxxxxxx
        subnetIds:
          - subnet-xxxxxxxx

參考資料
  1. Configuring a Lambda Function to Access Resources in an Amazon VPC
  2. How can I grant Internet access to my VPC Lambda function?
  3. Comparison of NAT Instances and NAT Gateways
  4. Scenario 2: VPC with Public and Private Subnets (NAT)
  5. (九)VPC與NAT Gateway--AWS經驗教學
  6. Outbound Internet access for Lambda in a VPC

沒有留言: