掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流

?HashiCorp Terraform 是一個(gè)IT基礎(chǔ)架構(gòu)自動(dòng)化編排工具,可以用代碼來管理維護(hù) IT 資源。Terraform的命令行接口(CLI)提供一種簡單機(jī)制,用于將配置文件部署到 AWS 或其他任意支持的云上,并對其進(jìn)行版本控制。它編寫了描述云資源拓?fù)涞呐渲梦募械幕A(chǔ)結(jié)構(gòu),例如虛擬機(jī)、存儲(chǔ)賬戶和網(wǎng)絡(luò)接口。
Terraform是一個(gè)高度可擴(kuò)展的工具,通過 Provider 來支持新的基礎(chǔ)架構(gòu)。Terraform能夠讓您在云上輕松使用簡單模板語言來定義、預(yù)覽和部署云基礎(chǔ)結(jié)構(gòu)。您可以使用Terraform來創(chuàng)建、修改、刪除ECS、VPC、RDS、SLB等多種資源。
在本文中,我們將了解如何使用 Terraform 管理現(xiàn)有和已創(chuàng)建的 AWS 安全組?;A(chǔ)設(shè)施革命的新時(shí)代已經(jīng)開始,我們已經(jīng)開始在配置管理工具(如 Ansible、Terraform、SaltStack 等)的幫助下以代碼的形式配置、管理和管理我們的基礎(chǔ)設(shè)施。
如果您是 Terraform 的新手并且想了解如何將 Terraform 與 AWS 基礎(chǔ)知識(shí)結(jié)合使用,可以參考本文。
我們知道 Terraform 很強(qiáng)大,我們可以使用 Terraform 高效的管理或創(chuàng)建整個(gè) AWS/GCP/DigitalOcean 云基礎(chǔ)設(shè)施,但我們經(jīng)常發(fā)現(xiàn)自己有一些額外的資源,這些資源通常是早期手動(dòng)創(chuàng)建的,而不是由 Terraform 管理的。
將所有這些非托管資源(安全組)引入 Terraform 并使它們成為基礎(chǔ)設(shè)施即代碼。我們可以使用Terraform import命令。
但是將這些資源一一導(dǎo)入是非常麻煩的。所以我們嘗試使用 Ansible 將其自動(dòng)化,結(jié)果就是這樣。
盡管如此,許多 DevOps 工程師仍在登錄 AWS 管理控制臺(tái)以手動(dòng)更新安全組入站和出站流量路由,例如打開端口、啟用流量路由等。這沒有任何問題,但問題是您無法跟蹤您的團(tuán)隊(duì)所做的更改除非您將其統(tǒng)一使用版本控制來管理。這就是 Infra as code 的優(yōu)勢所在。
想象一下,您將安全組作為代碼,并且您所做的每項(xiàng)更改都在您的 Git 存儲(chǔ)庫(如 BitBucket 或 Github)中正確提交和管理。每個(gè)更改都將使用 git 日志和提交消息進(jìn)行跟蹤,并且還會(huì)有配置的備份,以防您想要回滾。不僅如此。
我列出了您應(yīng)該將 AWS 安全組作為代碼進(jìn)行管理的幾個(gè)原因。
因此,將您的 AWS 安全組作為代碼來管理是非常高效的。
所以現(xiàn)在讓我們看看我是如何設(shè)法將我現(xiàn)有的 AWS 安全組(所有安全組)導(dǎo)入 Terraform 并對其進(jìn)行管理的。
我是 Ansible 和 Terraform 的粉絲,兩者在管理基礎(chǔ)設(shè)施方面都很棒,而 Ansible 是 pythonic,Terraform 有自己的語言,稱為 Hashicorp 配置語言,也支持 JSON。
我們在這里使用 Python 的原因是我們將使用 Ansible 的ec2_group_facts模塊獲取所有安全組及其信息,這也可以使用 AWS CLI 完成,但我更喜歡這種方式來更好地處理數(shù)據(jù)。
這是我們的設(shè)計(jì)將如何進(jìn)行的圖示。
如果您看不懂我的圖,我在這里寫下相同的內(nèi)容以供參考。
在我們的設(shè)置中。Ansible playbook 是使用模塊調(diào)用 Terraform 和 EC2 數(shù)據(jù)收集的主要組件ec2_group_facts。
為了讓 Ansible 能夠訪問 AWS,您需要在環(huán)境變量中啟用 AWS 編程訪問和身份驗(yàn)證密鑰。
$ export AWS_ACCESS_KEY_ID=AK************IEVXQ
$ export AWS_SECRET_ACCESS_KEY=gbaIbK*********************iwN0dGfS
這足以使 Ansible 和 Terraform 能夠訪問您的 AWS 基礎(chǔ)設(shè)施。但是,您可能會(huì)遇到一些隱藏的細(xì)節(jié)和問題(就像我遇到的那樣)如果您遇到困難或在評(píng)論中讓我知道,您可以參考以下文章,我會(huì)盡快提供幫助
為 Ansible 和 Terraform 準(zhǔn)備好您的環(huán)境后,我們可以繼續(xù)進(jìn)行。
"
完成 AWS 和 Ansible 集成的訪問設(shè)置后,您將能夠從 ansible 訪問您的 AWS 帳戶并執(zhí)行所有 AWS 相關(guān)模塊。
在本 playbook 中,我們還將使用這樣一個(gè)名為的模塊ec2_group_facts,它可以幫助我們獲取有關(guān)安全組的所有信息。那將是我們的第一步。
然后我們將為從 AWS 帳戶獲取的每個(gè)安全組創(chuàng)建一個(gè)目錄,并使用terraform import命令和安全組 ID創(chuàng)建 Terraform 配置文件。
導(dǎo)入完成后,我們需要?jiǎng)h除 terraform 配置文件中的一些配置元素,例如ownerid、arn、group id等,這些值/元素應(yīng)該由 Terraform 自動(dòng)填充,因此 terraform 不會(huì)讓您事先定義它。
從配置文件中刪除這些自動(dòng)生成的元素/變量后,我們將使用以下terraform validate命令驗(yàn)證文件。
因此,這些是我們要執(zhí)行的四個(gè)步驟,以使您的所有安全組都由 Terraform 管理。
所以,是時(shí)候編寫一些代碼了,理論就夠了。
執(zhí)行劇本之前要記住的幾點(diǎn):
The Playbook
---
- name: Security Group Playbook
hosts: localhost
vars:
destdir: /apps/gritfy/Terraform/SecGroups
itemstochange: ['arn\s+=.+$','\sid\s+=.+$','owner_id\s+=.+$']
tasks:
- name: ec2 security group information fetch
ec2_group_facts:
filters:
vpc-id: vpc-0a8ae2c90f5ca6cfa
register: result
- name: Creating a dictionary of Security Group IDs and Names
set_fact:
secdict: "{{ secdict | default ([]) + [ { 'name': item.group_name.replace(' ','-'), 'id': item.group_id } ] }} "
with_items: "`result`.`security_groups`"
loop_control:
label: "` item`.`group_name`"
- name: Create the Directory
file:
path: "`destdir`/`item`.`name`{{item.id[0:7]}}" # required. Path to the file being managed.
state: directory
register: dircrt
loop: "`secdict`"
- name: Terraform Import
shell: |
git init
echo 'provider "aws" {\n\tregion = "us-east-1"\n} \n\nresource "aws_security_group" "elb_sg" {\n\n}' > main.tf
terraform init
terraform import aws_security_group.elb_sg {{item.id}}
echo 'provider "aws" {\n\tregion = "us-east-1"\n} \n' > main.tf
terraform show -no-color >> main.tf
git add .
git status
git commit -m "Updated Git"
pwd && ls -lrt
args:
chdir: "`destdir`/`item`.`name`{{item.id[0:7]}}"
loop: "`secdict`"
when: dircrt is changed
- name: Change config
lineinfile:
path: "`destdir`/`item`.`0`.`name`{{item.0.id[0:7]}}/main.tf"
regexp: "` item`.`1 `"
state: absent
backup: yes
with_nested:
- "` secdict `"
- "` itemstochange `"
- name: Terraform Validate
shell: |
terraform validate
args:
chdir: "`destdir`/`item`.`name`{{item.id[0:7]}}"
loop: "`secdict`"
register: tfvalidate
failed_when: "'Success' not in tfvalidate.stdout"
讓我們?yōu)g覽一下劇本,了解每項(xiàng)任務(wù)的設(shè)計(jì)目的。
此任務(wù)使用名為的模塊ec2_group_facts?,它使用您環(huán)境中的 AWS 訪問密鑰和秘密直接連接到您的 AWS 帳戶并獲取所有屬于vpc?參數(shù)中提到的特定的安全組。確保vpc-id在運(yùn)行劇本之前更新過濾器值。
ec2_group_facts 模塊會(huì)產(chǎn)生很多關(guān)于安全組的信息,但我們只需要一個(gè)security group name和security group id
因此,我們正在遍歷上一個(gè)任務(wù)收集的輸出并創(chuàng)建一個(gè)名為secdict?我們正在使用set_fact模塊在運(yùn)行時(shí)創(chuàng)建變量的字典
如前所述,我們將為每個(gè)安全組創(chuàng)建專用目錄,其中將保存相應(yīng)安全組的 Terraform 配置文件。
此目錄的名稱將是安全組名稱和安全組 ID 的前 7 個(gè)字符的組合,這是為了避免重復(fù)。AWS 對安全組的命名沒有唯一名稱約束,因此可以有多個(gè)同名的安全組。
在此任務(wù)中,我們正在一個(gè)接一個(gè)地運(yùn)行多個(gè)命令,就像我們在 shell 提示符下鍵入一樣。使用ansible shell 模塊
這些是我們將要完成的任務(wù)列表:
在此任務(wù)中,我們將從創(chuàng)建的main.tf配置文件中刪除不需要的行,否則會(huì)使文件在語法上不正確。
最后,我們可以使用將在所有安全組目錄中執(zhí)行的命令來驗(yàn)證 Terraform 配置文件main.tf?是否對每個(gè)安全組有效。當(dāng)驗(yàn)證命令使用ansible failed_whenterraform validate?返回失敗消息時(shí),則為失敗(https://www.middlewareinventory.com/blog/ansible-changed_when-and-failed_when-examples/)
如果你做的一切都是正確的。您將能夠在您的 AWS 賬戶中導(dǎo)入屬于特定 VPC 的所有安全組,并且能夠使用Terraform 進(jìn)行管理。
您將在 playbook 中定義的 workspace(destdir) 目錄下使用安全組名稱創(chuàng)建目錄。
導(dǎo)入配置文件并準(zhǔn)備就緒后,轉(zhuǎn)到創(chuàng)建的任何安全組目錄并編輯main.tf文件并進(jìn)行更改,例如添加新的入口規(guī)則或更改允許的端口號(hào)的 CIDR IP 地址等。
完成更改后。我們就可以使用terraform plan?然后terraform apply它
我們將能夠看到我們的安全組已由 Terraform 成功管理。

我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流