基礎設施即代碼(Infrastructure-as-Code,IaC)意味著使用代碼來定義和管理基礎設施,而不是使用手動流程。更重要的是,IaC是將軟件工程原則和方法引入云基礎設施。本文將探討IaC的基礎知識以及如何設置相關環境。
IaC簡介
在IaC之前,基礎設施是(某些情況下現在仍然是)通過簡單操作用戶界面、批處理腳本和配置管理工具等方法提供的,這些方法并不適用于當今的云計算。
同樣,當下很多所謂的IaC其實很大程度上更接近于“基礎設施即文本”。作為以結構化文本編寫的基礎設施,它是可重復并且可以進行版本控制的。但是,在實施需要與應用程序代碼一起使用的軟件工程時,它就無法勝任了。例如,無法支持標準開發工具、測試框架或包管理。
真正意義上的IaC方案需要使用專為云上基礎設施設計的平臺,從而使標準軟件工程實施方案和工具都能夠得以應用。
IaC為什么非常重要?
IaC之所以重要,主要有三個原因:
一是當下企業向云的全面遷移。越來越多的工作負載正在從本地數據中心遷移到云端,并且這種趨勢會一直持續下去。然而,云計算本身并不是能夠保證和維持基礎設施可靠而又可擴展的靈丹妙藥。與物理數據中心一樣,云基礎設施的腳本集也可能存在不一致、文檔記錄不充分等情況。由于IaC是強制執行經過驗證的工程實施步驟,從而能夠將混亂的狀況整理得秩序井然。
二是公眾使用云的方式更加復雜。商業用戶嘗試改變設施、模式和工作方式,以改善收益。IaC不只是簡單的資本支出與運營支出,而是關乎如何整合構成工程生命周期的所有因素,例如版本控制和測試,以釋放云可以提供的所有價值。它能夠使用工程實踐來充分挖掘云計算的潛力,從而更好更快地推動創新進而推動公司業務。
三是管理云上基礎設施的負荷不斷在增加。可用的云服務種類每年都在增長,越來越多的公司正在采用現代云設施(比如容器或無服務器設施)。這些設施往往包含許多松散耦合和相互依賴的組件,從而導致工程師必須管理的云資源數量以驚人的速度增長。這當然是一件好事,因為這意味著商業用戶正在從云上獲得更多收益,推動了公司業務發展,但結果是云資源的復雜性和規模不斷增加。
例如,從云上獲取收益的方法之一是充分利用云供應商提供的越來越多的服務。這些服務可以推動創新并加快業務進展。但同時,每一項新服務都會帶來新的API,這會增加基礎設施的復雜性。
隨著云資源規模和復雜性的增加,現代的IaC方法就是亟需的了。它可以幫助工程師構建、部署和管理基礎設施。如果工程師管理的資源介于1到10個之間,那么簡單的點擊就可能能正常工作;當管理10到100個資源時,“基礎設施即文本”或舊版IaC工具可能仍然能勝任。
但是一旦資源數目到了成百上千或成千上萬時會發生什么?這在今天并不罕見!最重要的是,這成千上萬的資源不是每月更新一次,而是每天更新多次。管理好這一切的最佳途徑是將用于應用程序代碼的相同軟件工程實施方案和工具落實到位。
思考下列問題:
(1)如何確保我的基礎設施能夠快速擴展、更改和發展,以支持業務并創造競爭優勢?
(2)如何保持云基礎設施以及對其任何更改的可見性?
(3)如何制定策略和數據護欄來確保安全性和可靠性?
(4)如何通過更好的協作和流程,最科學地授權我的團隊構建、部署和管理基礎設施?
要解決以上問題需要一種現代的IaC方法。現代的IaC方法是充分挖掘云計算潛力的方式。
使用IaC的重要注意事項
IaC平臺的選擇至關重要。如果使用者意欲使用已有的標準軟件工程工具和操作,那么在選擇時就要注重以下特點:
1.標準語言
對標準語言的良好支持,意味著開發人員可以方便地使用相同的應用程序代碼語言來定義和配置基礎設施,例如TypeScript、Go、Python和C#等常用語言。很多舊版的IaC工具使用自己的域特定語言 (DSL),這可能會導致一些問題,比如開發人員經常發現缺少常見的編程設施。
在所選擇的平臺上,工程師應該能夠輕松創建強類型化、設施化的配置,并使用他們一直所依賴的功能,例如循環、常量和函數。并且,使用標準語言的另一個優勢是開發人員對此早已熟悉,他們可以立即開始編碼。若是需要再去學習DSL的特性和局限性,大概是一件既耗費時間又令人沮喪的事情。
2.標準開發工具
使用標準編程語言意味著開發人員還可以使用標準開發工具,例如IDE。一個優點依然是熟悉程度,開發人員可以在他們習慣的環境中工作;另一個則是開發人員得以在一個能輕松編寫、調試、測試和部署代碼的環境中大顯身手。
3.測試框架
與應用程序一樣,對基礎設施進行徹底的測試非常重要。合格的IaC 平臺應當支持標準測試框架,還應該能夠幫助團隊擴展其執行的測試類型。
標準運維測試側重于驗收測試。這意味著運維團隊在云中啟動基礎設施,然后測試它們以查看是否完整無誤。毫無疑問,如果它沒有正確啟動,運維團隊需要將其銷毀并重新部署。但這并不是一個最佳方法,因為可能不應該發生的事情已經發生了,這取決于團隊的反應速度。合格的IaC平臺應當通過部署前和部署期間的頻繁測試來幫助團隊“轉移風險”。如果上述步驟還沒有執行,那么團隊應能使用IaC平臺執行以下類型的測試:
(1)單元測試
單元測試單獨評估基礎設施的行為。外部依賴項(例如數據庫)被替換為模擬,以檢查資源配置和響應。之所以使用模擬是因為來自云服務供應商的響應是眾所周知的并經過測試的。測試者已經知道給定一些參數后供應商將如何響應。
單元測試在內存中運行,沒有任何進程外調用,這使得它們非常快。在開發過程中可以使用它們進行快速反饋循環。單元測試確實可以幫助開發人員在基礎設施生命周期的早期解決問題。
(2)集成測試
集成測試(也稱為黑盒測試)單元測試之后進行,它采用不同的方法。集成測試部署云資源并驗證它們的實際行為——當然是在一個臨時環境中。臨時環境是模擬生產環境的短期環境。它通常很簡單,且只包括正在測試的代碼的第一級依賴項。集成測試完成后,可以銷毀臨時基礎設施。
(3)安全測試
很多時候,安全測試被留到最后一刻,或者當做是“完成”的代碼扔給安全團隊,他們被排除在整個開發過程之外實際上,這種思路可以說是“自尋死路”。
現代IaC平臺應該加密敏感的配置數據,并使遵循標準的安全實施(例如密鑰輪換)能夠順利執行。還要檢查平臺是否加密了狀態元數據,并確保機密值永遠不會以純文本形式公開。該平臺還應與云提供商提供的安全服務能夠輕松無障礙集成。
此外,與其他類型的測試一樣,IaC平臺應該幫助開發人員將自己編寫的安全測試添加到工作流程中。正如盡早對代碼實施單元測試一樣,你也應該盡早測試以發現安全問題。這些測試屬于 CI/CD 管道,因此基礎設施在發布之前會進行徹底的漏洞測試。
4.創建可重用組件
可重用組件意味著開發人員可以從單個組件中構建更高級別的資源。有了它們,工程師就能夠創建可以在其他地方重用的有用抽象。這些組件可以使用公司內部的最佳實踐方案來編寫,并在內部和社區內共享。使用可重用組件有助于創建可重復、可靠的基礎設施。所以,要認真研究你正在考慮的平臺能否輕松創建這些組件。
5.標準包管理器
如若創建可重用的組件,則需要一種方法來打包它們,以便可以輕松實現共享。除了使用標準工具外,還需要對標準包管理器的支持。例如,開發人員可能希望將組件放入 GitHub存儲庫并通過NPM發布。那么IaC平臺應該能夠輕而易舉做到這一點。
6.創建行為可見
為便于明確責任和相互協作,所有基礎設施資源的集中可見,更迭變化的歷史視圖可見,這些都很重要。開發人員選擇的平臺應該具備日志審核以及云資源更改時差異可見的能力(類似于團隊使用Git等協作工具的方式),從而為開發人員提供整個基礎設施的可見性。此外,該平臺還應該可以設置細粒度的控制,以便控制哪些用戶可以訪問和更改基礎設施。
7.支持多個云供應商
并非每家公司都希望使用多個云供應商,但這是應該考慮到的事情。如果開發人員想要保留多個選項,那就選擇不會局限于單個云供應商的IaC平臺。
8.策略即代碼
另一個經常被忽視的IaC方面是策略即代碼。現代IaC平臺應該允許開發人員將軟件工程原則和方法應用于自己的策略,就像它對基礎設施所做那樣。策略即代碼的好處與基礎設施即代碼的好處大致相同。策略會在安全性、合規性以及成本控制方面持續實施組織的云治理。策略是明確的,可以使用標準語言和工具編寫,可以進行版本控制、測試并最終集成到 CI/CD 管道中,從而使所有基礎設施都遵循公司的最佳實施方案。
基礎設施即代碼工具
許多開源IaC工具可用于自動執行資源分配、部署和管理。使用的關鍵在于正確選擇適合自己的基礎設施自動化工具。以下是常見的IaC類別和工具:
使用Terraform實施基礎設施即代碼
Terraform是一個不受平臺所限平臺的開源工具,它允許開發人員將基礎設施編寫成為聲明性配置文件。Terraform支持眾多的云供應商,使得開發人員能夠在AWS、Google Cloud、Azure和Oracle等主流云平臺中配置資源。
借助Terraform,工程師可以快速擴展基礎設施資源的配置。自動化的部署過程能夠提高組織中開發團隊的工作效率,從而使他們可以更改部署基礎設施。并且Terraform有助于減少對于集中式基礎設施團隊的依賴,使開發團隊能夠更快地行動,縮短業務功能耗費的周期時間。
使用 Terraform 配置資源,請使用以下命令:
使用Terraform模塊創建可重用的基礎設施
Terraform模塊的概念很簡單——開發人員可以在模塊內編寫代碼,并在整個代碼庫的多個位置重用它。使用Terraform模塊,只需幾行代碼就可以快速構建基礎設施。隨著基礎設施的不斷繁衍,開發人員需要在不同的環境(如開發和過渡期)中部署相似的資源,誰也不希望反復多次地復制粘貼相同的代碼。
Terraform模塊更易于閱讀。它們強制執行最佳實施方案,開發人員不會在Terraform文件中進行硬編碼。為使模塊可以被不同的團隊重用并適應各種實例,需要使其可配置。并且能夠將附加參數傳遞給環境的多個資源。由于是經過嚴格測試和完全記錄的集中式模塊,因此Terraform非常可靠。
對于最佳實施方案來說,應當開始將基礎設施視為可重用的模塊。Terraform模塊能夠促進代碼的重用,避免重復,并有助于在組織內部共享模塊。使開發人員可以有更多時間精力來提高集中式可重用模塊的質量。
示例代碼:
下面是使用Terraform模塊在各種環境中創建AWS S3存儲桶所需的步驟。首先,我們使用AWS與所需資源進行交互。以下代碼配置AWS提供者:
1 terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "~> 4.9"
6 }
7 }
8 }
9
10 provider "aws" {
11 region = "us-east-1"
12 }
現在創建一個用于配置S3存儲桶資源的Terraform模塊:
1 resource "aws_s3_bucket" "s3-bucket" {
2 bucket = var.bucket
3 policy = var.policy != null ? var.policy : null
4 tags = merge(var.tags, { Name = "${var.bucket}-bucket" })
5
6 server_side_encryption_configuration {
7 rule {
8 apply_server_side_encryption_by_default {
9 sse_algorithm = "AES256"
10 }
11 }
12 }
13
14 dynamic "lifecycle_rule" {
15 for_each = var.expire-days > 0 ? [var.expire-days] : []
16 content {
17 id = "expire"
18 enabled = true
19 expiration {
20 days = var.expire-days
21 }
22 }
23 }
24 }
左右滑動查看完整代碼
該模塊支持各種參數,如存儲桶、策略、過期日以及標簽:
1 variable "bucket" {
2 description = "S3 Bucket Name"
3 type = string
4 }
5
6 variable "policy" {
7 description = "Optional S3 bucket policy to apply. Should be a valid JSON string"
8 type = string
9 default = null
10 }
11
12 variable "expire-days" {
13 description = "If set to positive number, lifecycle policy for expiring the objects after specified number of days will be attached to the bucket"
14 type = number
15 default = 0
16 }
17
18 variable "tags" {
19 description = "Common tags to be applied to all resources"
20 type = map(any)
21}
左右滑動查看完整代碼
由于已經創建了可重用的S3模塊,我們現在可以從各種環境(如dev或live)調用該模塊并傳入所需的變量。
1 module "dev-dzone-bucket" {
2 source = "../modules/s3-bucket"
3 bucket = "dev-dzone-iac-bucket"
4 policy = null
5 expire-days = 7
6 tags = local.tags
7 }
8
9 module "live-dzone-bucket" {
10 source = "../modules/s3-bucket"
11 bucket = "live-dzone-iac-bucket"
12 policy = null
13 expire-days = 14
14 tags = local.tags
15 }
左右滑動查看完整代碼
Terraform項目中的文件布局類似于下圖 ,在“terraform-modules”(即Terraform模塊)下包含用于開發和生產環境的單獨文件夾,其中包含 AWS 資源。
啟用IaC的工作清單
將現代IaC平臺引入初創公司,或者是具有許多綠地軟件項目的公司,可能并不困難。然而,對于大多數公司來說,卻并不是一件簡單的事情。許多公司,無論大小,都已經存在很多通過云供應商提供的簡易控制臺創建的基礎設施。很多新項目就是這樣簡單啟動的。然后,有一天,一位運維工程師幡然醒悟,意識到現在新項目是生產基礎設施。為了使其更加“正式”,運維團隊編寫了一本運行手冊或wiki,詳細解說如果有人想要執行一項常見任務,應該單擊哪些按鈕等等。還有一種常見的情況,那就是周圍全是只有一兩個人明白的Bash或PowerShell腳本。如果你面臨這樣的情況,你該怎么辦?
(1)保持冷靜
你應該明白的是,變化有時候可能是令人感到恐懼的。許多人一想到要觸及基礎設施,就感到好像要崩潰一樣。他們認為這太復雜了,搞不懂這個東西是如何工作的。所以,要有信心,才能解決問題。
(2)正確定義“完美”的概念?
開發人員應該在開始評估工具和方法之前,要明白對于公司來說“完美”是什么一個概念。開發人員無論使用何種工具,一些假設都是既定存在的。明白這些才能實現目標。團體決策是正確制定公司云基礎設施業務目標的途徑之一。
(3)選擇評估工具?
考慮上述關鍵點之后,將篩選完美平臺的選擇范圍縮小到幾個評估對象。開發人員可以設計一個小項目,目的是測試平臺,看它是否符合工作需求。
(4)導入現有基礎設施?
選擇工具之后,試著導入一些現有的基礎設施。如果開發人員選擇的平臺正確,這一步應該輕而易舉。
(5)與現有工程實施方案集成?
如果基礎設施代碼集成持續交付管道,則可以開始建立與應用程序代碼相同的最佳實施方案。
(6)從小處著手
新建一項服務或從非關鍵服務開始——這樣即使出問題也不會影響業務。選擇一個項目,盡快看到意義和價值,然后進行更新迭代。
結論
現代IaC是降低云復雜性、釋放云潛力從而推動創新的最佳途徑。選擇合適的平臺,使用現代IaC,開發人員可以將標準軟件工程實施方案和工具應用于基礎設施。大體來說,可以獲得以下幾點益處。
1.推動創新、提高速度和敏捷性
借助現代IaC,團隊可以將現代軟件開發中,相同的操作、嚴謹的測試和自動化應用于云基礎設施,從而提高發布的速度和可靠性,以便公司對客戶反饋做出快速反應并及時更新。
2.降低基礎設施風險
由于開發人員可以使用標準測試框架,因此IaC能夠“將風險轉移”。盡早的、充分和完全的測試可以成為開發過程以及CI/CD 管道的一部分。由于策略和安全要求也包含在代碼里,故每次部署都會自動測試合規性和安全性。
3.加強合作?
現代IaC平臺使用標準工具和語言,可以打破基礎設施、應用程序開發和安全團隊之間的孤島。大家使用共享的實踐方案和工具,能促進團隊之間的協作。
參考鏈接:https://dzone.com/refcardz/getting-started-with-iac