設定 Open虛擬私人網路 伺服器

啟動例項後,我們需要進行初始設定。以下是透過 SSH 連線到 Open虛擬私人網路 Access Server 並進行設定的步驟:

  1. 首先,使用 SSH 連線到伺服器:

    ssh -i ~/.ssh/yan-key-pair-apsydney.pem openvpnas@openvpn-ipaddress
    
  2. 初始登入時,Open虛擬私人網路 Access Server 設定精靈會自動執行,引導你完成設定過程:

    • 同意許可協定
    • 確認這是主要節點
    • 選擇網路介面(建議選擇所有介面:0.0.0.0)
    • 設定 Admin Web UI 連線埠(預設 943)
    • 設定 Open虛擬私人網路 守護程式的 TCP 連線埠(預設 443)
    • 設定客戶端流量和 DNS 路由選項
    • 選擇認證方式(通常使用本地認證)
    • 設定私有子網存取許可權
    • 設定管理員帳戶和密碼

關鍵設定要點

在設定過程中,有幾個值得特別注意的設定:

  1. 網路介面選擇:選擇 “all interfaces: 0.0.0.0” 允許從任何介面存取管理介面,這在雲環境中很有用,但在某些情況下可能需要限制為特定介面以提高安全性。

  2. 流量路由選項

    • “Should client traffic be routed by default through the 虛擬私人網路?” - 如果選擇 “yes”,所有客戶端流量都將透過 虛擬私人網路 路由,包括網際網路流量。
    • “Should client DNS traffic be routed by default through the 虛擬私人網路?” - 控制 DNS 查詢是否透過 虛擬私人網路 路由。
  3. 私有子網存取:在 EC2 環境中,通常希望 虛擬私人網路 客戶端能夠存取 VPC 中的私有子網,因此應選擇 “yes”。

管理 Web 介面設定

完成初始設定後,可以透過 Web 介面進行更詳細的設定:

  1. 存取 https://openvpn-ipaddress/admin

  2. 在 虛擬私人網路 Settings 選單中:

    • 設定動態 IP 地址網路,例如 10.1.0.0/23,用於分配給 虛擬私人網路 客戶端
    • 根據需要設定靜態 IP 地址網路和群組預設 IP 地址網路
  3. 增加使用者:

    • 轉到 User Permissions 選單
    • 增加使用者名
    • 設定密碼
    • 更新執行中的伺服器

客戶端連線

使用者可以透過以下方式連線到 虛擬私人網路:

  1. 存取 https://openvpn-ipaddress
  2. 選擇直接透過瀏覽器連線到 虛擬私人網路
  3. 或者登入後下載使用者設定檔案 (client.ovpn),在 Open虛擬私人網路 客戶端中使用

自動化佈署的效益與最佳實踐

使用 Ansible 自動化 AWS 基礎設施佈署帶來諸多好處:

一致性與可重複性

透過自動化指令碼,每次佈署都能獲得一致的結果,不受人為因素影響。玄貓在多個專案中發現,自動化佈署不僅減少了設定錯誤,還顯著提高了環境一致性。

時間效率

手動設定 VPC、安全群組和 Open虛擬私人網路 可能需要數小時,而使用 Ansible 可以在幾分鐘內完成。這對於需要頻繁建立或更新環境的團隊特別有價值。

版本控制與協作

將基礎設施設定儲存為程式碼,可以使用 Git 等工具進行版本控制,促進團隊協作並提供變更歷史記錄。這種方法使基礎設施變更加透明和可追溯。

最佳實踐

在實施自動化佈署時,玄貓建議遵循以下最佳實踐:

  1. 變數分離:將環境特定變數(如區域、VPC ID 等)與 playbook 邏輯分離,

Ansible 與 AWS VPC 資源管理的自動化挑戰

在現代雲端架構中,基礎設施即程式碼(Infrastructure as Code, IaC)已成為標準實踐。然而,當我們使用 Ansible 管理 AWS Virtual Private Cloud (VPC) 資源時,常會遇到一些實用性的挑戰。特別是在識別和管理已存在的 VPC 資源時,標準模組可能無法完全滿足需求。

在這篇文章中,我將分享一個實用的解決方案,透過自定義 Ansible 模組來根據資源標籤查詢 VPC 和子網路 ID,這樣我們就不需要硬編碼這些 ID 到設定檔案中。這種方法不僅提高了自動化程度,也大幅增加了基礎設施管理的彈性。

突破 Ansible 的 VPC 管理限制

在使用 Ansible 管理 AWS 基礎設施時,常見的痛點是標準模組對 VPC 資源管理的限制。特別是當需要根據標籤或其他屬性查詢 VPC 和子網路 ID 時,Ansible 內建模組缺乏直接支援。

這導致許多團隊不得不將這些 ID 直接寫入設定檔案或變數中,這種做法不僅缺乏靈活性,還增加了維護成本。當基礎設施規模擴大,管理多個環境或區域時,這個問題會變得更加明顯。

自定義 Ansible 模組:vpc_lookup

為瞭解決這個問題,我們可以建立一個自定義的 Ansible 模組,專門用於根據資源標籤查詢 VPC 和子網路 ID。這個模組使用 Python 和 boto 函式庫AWS API 通訊,實作了根據標籤的資源查詢功能。

首先,讓我們建立模組目錄並編寫模組程式碼:

$ cd /home/yan/ansible4aws
$ mkdir library
$ vi library/vpc_lookup

以下是完整的 vpc_lookup 模組程式碼:

#!/usr/bin/python

import sys

AWS_REGIONS = ['ap-northeast-1',
               'ap-southeast-1',
               'ap-southeast-2',
               'eu-west-1',
               'sa-east-1',
               'us-east-1',
               'us-west-1',
               'us-west-2']

try:
    from boto.vpc import VPCConnection
    from boto.vpc import connect_to_region
except ImportError:
    print "failed=True msg='boto required for this module'"
    sys.exit(1)

def main():

    module=AnsibleModule(
        argument_spec=dict(
            region=dict(choices=AWS_REGIONS),
            aws_secret_key=dict(aliases=['ec2_secret_key', 'secret_key'],
                               no_log=True),
            aws_access_key=dict(aliases=['ec2_access_key', 'access_key']),
            tags=dict(default=None, type='dict'),
        )
    )

    tags = module.params.get('tags')
    aws_secret_key = module.params.get('aws_secret_key')
    aws_access_key = module.params.get('aws_access_key')
    region = module.params.get('region')

    # If we have a region specified, connect to its endpoint.
    if region:
        try:
            vpc = connect_to_region(region, aws_access_key_id=aws_access_key,
                                   aws_secret_access_key=aws_secret_key)
        except boto.exception.NoAuthHandlerFound, e:
            module.fail_json(msg=str(e))
    else:
        module.fail_json(msg="region must be specified")

    subnet_ids = []
    for tag, value in tags.iteritems():
        for subnet in vpc.get_all_subnets(filters={"tag:" + tag: value}):
            subnet_ids.append(subnet.id)

    vpc_ids = []
    for tag, value in tags.iteritems():
        for vpc in vpc.get_all_vpcs(filters={"tag:" + tag: value}):
            vpc_ids.append(vpc.id)

    module.exit_json(changed=False, vpc_ids=vpc_ids, subnet_ids=subnet_ids)


# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>

main()

這段程式碼建立了一個名為 vpc_lookup 的 Ansible 模組,用於根據標籤查詢 AWS VPC 和子網路 ID。讓我來解析其中的關鍵部分:

  1. AWS 區域定義:程式碼首先定義了支援的 AWS 區域列表,確保使用者只能使用有效的區域。

  2. Boto 函式庫:模組依賴 boto 函式庫AWS API 通訊,如果未安裝則會回傳錯誤。

  3. 引數定義:使用 AnsibleModule 定義模組的輸入引數,包括 AWS 區域、認證訊息和資源標籤。

  4. 連線建立:根據提供的區域和認證資訊建立與 AWS VPC 服務的連線。

  5. 資源查詢:使用 boto 的 get_all_subnetsget_all_vpcs 方法,配合標籤過濾器查詢符合條件的資源。

  6. 結果輸出:模組回傳 JSON 格式的結果,包含查詢到的 VPC ID 和子網路 ID 列表。

最後,別忘了設定模組的執行許可權:

$ chmod 755 library/vpc_lookup

使用自定義模組管理 VPC 資源

現在我們可以在 playbook 中使用這個自定義模組來查詢和管理 VPC 資源。以下是一個實際的例子,展示如何查詢特定標籤的 VPC 並刪除它:

---
- hosts: localhost
  connection: local
  gather_facts: no
  vars:
    region: ap-southeast-2
  tasks:
    - name: get vpc id
      vpc_lookup:
        region: "{{ region }}"
        tags:
          Name: test-vpc
      register: vpc

    - name: delete vpc
      ec2_vpc:
        region: "{{ region }}"
        state: absent
        vpc_id: "{{ item }}"
        wait: yes
      with_items: vpc.vpc_ids

這個 playbook 執行兩個主要任務:

  1. 查詢 VPC ID:使用我們的自定義模組 vpc_lookup 查詢標籤為 “Name=test-vpc” 的 VPC,並將結果儲存在 vpc 變數中。

  2. 刪除 VPC:使用 Ansible 的 ec2_vpc 模組刪除查詢到的 VPC,使用 with_items 迴圈處理可能的多個結果。

這種方法的優點是完全根據標籤進行資源管理,無需在 playbook 中硬編碼 VPC ID,大提高了設定的靈活性和可重用性。

進階技巧:子網路查詢與管理

同樣的模組也可以用於查詢子網路 ID。當你需要根據標籤查詢特定子網路時,可以使用相同的 vpc_lookup 模組,但在結果處理時使用 subnet_ids 欄位:

- name: get subnet id
  vpc_lookup:
    region: "{{ region }}"
    tags:
      Name: private-subnet
  register: subnet_result

- name: use subnet id
  ec2_instance:
    region: "{{ region }}"
    subnet_id: "{{ subnet_result.subnet_ids[0] }}"
    # 其他引數...

Ansible 2.1 新增的官方模組

值得一提的是,從 Ansible 2.1 版本開始,官方增加了兩個新模組來解決類別似問題:

  1. ec2_vpc_net_facts:用於收集 VPC 的詳細資訊
  2. ec2_vpc_subnet_facts:用於收集子網路的詳細資訊

這些模組提供了更標準化的方式來查詢 VPC 資源。例如:

- name: Get VPC facts
  ec2_vpc_net_facts:
    region: "{{ region }}"
    filters:
      "tag:Name": "test-vpc"
  register: vpc_facts

- debug:
    var: vpc_facts.vpcs[0].id

雖然這些官方模組提供了更豐富的功能,但我們的自定義模組在某些場景下可能更加簡潔直接,特別是當你只需要 ID 訊息時。

實戰經驗分享:資源標籤策略

在實際工作中,玄貓發現制定一個一致的資源標籤策略對於 VPC 資源管理至關重要。以下是我常用的標籤策略:

  1. 環境標籤:使用 Environment 標籤(如 prod、staging、dev)區分不同環境的資源
  2. 專案標籤:使用 Project 標籤關聯資源與特定專案
  3. 功能標籤:使用 Function 標籤(如 database、application、cache)描述資源用途
  4. 管理標籤:使用 ManagedBy 標籤記錄資源的管理工具(如 Ansible、Terraform)

這種標籤策略不僅有助於資源查詢,還能實作更精細的成本分析和資源管理。

模組開發的最佳實踐

在開發自定義 Ansible 模組時,我總結了一些最佳實踐:

  1. 引數驗證:始終驗證輸入引數,確保必要引數存在與有效
  2. 錯誤處理:優雅處理錯誤並提供清晰的錯誤訊息
  3. 安全性考慮:對敏感資訊(如 AWS 金鑰)使用 no_log=True 防止記錄
  4. 冪等性設計:設計模組使其可以重複執行而不產生副作用
  5. 檔案完整性:提供詳細的模組檔案,包括引數說明和使用範例

遵循這些實踐可以確保自定義模組與 Ansible 生態系統無縫整合,同時提供良好的使用者經驗。

自動化 VPC 管理

隨著雲端基礎設施的不斷發展,VPC 資源管理的自動化需求也在不斷演進。玄貓認為未來的發展趨勢包括:

  1. 跨雲供應商的統一管理:同時管理 AWS、Azure 和 GCP 的虛擬網路資源
  2. 更人工智慧的資源推薦:根據使用模式自動推薦最佳的 VPC 設計
  3. 安全合規自動化:自動檢測和修復 VPC 設定中的安全問題
  4. 根據意圖的網路設定:使用自然語言描述網路需求,自動生成相應的 VPC 設定

自定義模組的開發能力將在這些趨勢中發揮關鍵作用,使團隊能夠靈活應對不斷變化的需求。

實踐建議

在 AWS 雲環境中使用 Ansible 管理 VPC 資源時,標準模組的限制可能會影響自動化的效率和靈活性。透過開發自定義模組如 vpc_lookup,我們可以實作根據標籤的資源查詢,避免硬編碼 ID 的問題。

這種方法不僅提高了設定的可維護性,還為更複雜的自動化流程奠定了基礎。雖然 Ansible 2.1+ 提供了官方的資源查詢模組,但瞭解如何開發和使用自定義模組仍然是提升自動化能力的重要技能。

最後,記住良好的標籤策略是高效 VPC 管理的根本。無論使用哪種工具或模組,一致與有意義的資源標籤都能大幅簡化管理工作,並為未來的自動化奠定堅實基礎。