為您的Amazon基礎設施提供強大的Terraform AWS Provider

如果您計劃管理並使用Amazon Web Services (AWS),使用TerraformAWS provider是必不可少的。它使您能夠與AWS支持的眾多資源互動,例如Amazon S3Elastic BeanstalkLambda等等。

在這份終極指南中,您將逐步學習有關AWS提供者的幾乎所有必要知識,以及如何使用這個提供者與Terraform一起管理您的Amazon基礎設施。

讓我們開始吧!

先決條件

如果您想跟隨這個教程,請確保您已經做好以下準備:

  • A code editor – Even though you can use any text editor to work with Terraform configuration files, you should have one that understands the HCL Terraform language. Try out Visual Studio (VS) Code.

Terraform AWS Provider 是什麼?

Terraform依賴於插件與雲端提供商(如AWS、Google Cloud Platform(GCP)和Oracle)進行交互。其中最廣泛使用的提供商之一是AWS提供商。該提供商與AWS支持的許多資源進行交互,例如Amazon S3Elastic BeanstalkLambda等等。

Terraform使用帶有正確憑證的AWS Provider連接到Amazon,以管理或部署/更新數十個AWS服務。

AWS Provider在Terraform配置文件中聲明,並包括各種參數,如版本、端點URL或雲端區域等。

聲明AWS Provider

當您需要引用供應商的名稱時,必須定義一個本地名稱。本地名稱是指在required_providers區塊內分配的供應商名稱。在需要供應商時分配本地名稱,每個模塊必須是唯一的。

在聲明required_providers時,您還需要在 Terraform 0.13 及更新版本中聲明source參數。source參數設置 Terraform 可以下載插件的來源地址。

來源地址由三部分組成,如下:

  • 主機名 – 分發供應商的 Terraform 注冊表的主機名。默認主機名為registry.terraform.io
  • 命名空間 – 指定的注冊表內的組織命名空間
  • 類型 – 類型是您為供應商管理的平台或系統提供的簡短名稱,它必須是唯一的。

下面,您可以看到源參數的聲明語法,其中源地址的三個部分由斜杠(/)分隔。

## <HOSTNAME>/]<NAMESPACE>/<TYPE>

# SOURCE PARAMETER SYNTAX使用範例

# 声明 Terraform 可以下载插件的源位置/地址
# 官方的 AWS 供应商属于 hashicorp 命名空间
# registry.terraform.io 注册表。 因此,hashicorp 的源地址是 hashicorp/aws
source  = "hashicorp/aws"

現在下面的 Terraform 配置聲明了所需提供者的名稱(aws),以及源地址、AWS 提供者版本,以及配置提供者的地區(us-east-2

# 在安装了 Terraform 0.13 及更高版本后声明提供者要求
terraform {
  # 提供者要求包括本地名称(aws)、
  # 源位置和版本约束。
  required_providers {
    aws = {     
      # 声明 Terraform 可以下载插件的源位置/地址
      source  = "hashicorp/aws"
      # 声明 aws 提供者的版本大于 3.0
      version = "~> 3.0"  
    }
  }
}

# 配置 AWS 提供者在 us-east-2 地区
provider "aws" {
  region = "us-east-2"
}

使用硬编码凭证认证 AWS 帐户

现在您已经基本了解了如何声明 AWS 提供者,让我们看看如何对 AWS 帐户进行身份验证。

您可以通過幾種不同的方法驗證AWS提供者,例如聲明環境變量和在命名配置檔案中儲存憑證。但是,驗證AWS帳戶的最快方式是在您的AWS提供者中硬編碼憑證。

雖然不建議使用硬編碼憑證,因為它們容易洩露,但您仍然可以在Terraform配置中聲明硬編碼憑證,以快速測試任何AWS資源。但是繼續閱讀,您稍後將學到通過聲明環境變量驗證AWS帳戶的更好方法。

下面的配置聲明了一個本地名稱(`aws`)以及提供者地區(`us-east-2`),如下所示。您可以看到AWS提供者塊還聲明了一個訪問鍵和秘密鍵來驗證AWS帳戶。

# 聲明名為aws的AWS提供者
provider "aws" {
  # 聲明提供者地區
  region = "us-east-2"
  # 聲明access_key和secret_key
  access_key = "access-key"
  secret_key = "secret-key"
}

通過聲明環境變量來保護憑證

您剛剛學到,使用Terraform硬編碼靜態憑證來驗證AWS雲服務是可能的。但是,硬編碼不安全,只推薦在測試環境中部署時使用,以快速測試代碼。

是否有其他方法来保护凭据?是的,可以将它们声明为环境变量,您可以声明任意数量的环境变量。环境变量是在terraform配置文件之外设置值的变量,由名称/值对组成。

运行下面的一系列export命令来导出每个环境变量。导出环境变量使它们在整个程序中可用,直到Terraform执行。

# 导出变量 AWS_ACCESS_KEY_ID
export AWS_ACCESS_KEY_ID="access-key"
# 导出变量 AWS_SECRET_ACCESS_KEY
export AWS_SECRET_ACCESS_KEY="secret-key"
# 导出变量 AWS_DEFAULT_REGION
export AWS_DEFAULT_REGION="us-east-2"

将多个凭据存储在命名配置文件中

无论是硬编码还是将凭据声明为环境变量,都可以一次验证一个AWS帐户。但是,如果您需要存储多个凭据并在需要时使用它们怎么办?将凭据存储在命名配置文件中是理想的选择。

下面的代码创建一个名为(Myprofile)的命名配置文件,其中包含一个访问密钥和秘密密钥。

命名配置文件的默认位置是在Linux和macOS上的$HOME/.aws/credentials/Myprofile,或者在Windows上的%USERPROFILE%\.aws\credentials\Myprofile。请用实际的命名配置文件名称替换Myprofile。

# 建立名為 'Myprofile' 的命名配置檔
[Myprofile]
aws_access_key_id = AKIAVWOJMI5836154yRW31
aws_secret_accesss_key = vIaGmx2bJCAK90hQbpNhPV2k5wlW7JsVrP1bm9Ft

一旦在 ~/.aws/credentials 中建立了一個命名配置檔,您就可以在 Terraform 配置中使用 profile 屬性來引用該配置檔。下面,您正在引用名為 Myprofile 的命名配置檔。

# 在 us-east-2 區域配置名為 'aws' 的 AWS 提供者
provider "aws" {
  region = "us-east-2"
  # 宣告命名配置檔(Myprofile)
  profile = "Myprofile"
}

在 AWS 提供者中宣告 Assume Role

您剛剛學會了在運行 Terraform 之前通過宣告硬編碼憑證來配置 AWS 提供者。但也許,您想在運行時宣告憑證。如果是這樣,那麼 AssumeRole API 就是您需要的。AssumeRole 提供了包含訪問金鑰 ID、秘密訪問金鑰和 安全令牌 的臨時憑證。這些憑證允許您連接到 AWS。

以下代碼宣告了名為 awsprovider 和包含角色名稱和會話名稱的 assume_role。要配置 AssumeRole 訪問,您必須定義一個指定了其授予的特權和可以假定它的實體的 IAM 角色。

# 声明名为 'aws' 的 AWS 提供者
provider "aws" {
  # 声明 AssumeRole
  assume_role {
		# 声明资源名称。
    # role_arn 是要假设的 IAM 角色的 Amazon 资源名称 (ARN)。
    # ARN 是与 AWS 帐户中的所有资源对齐的唯一编号。
    role_arn     = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
    # 声明会话名称
    session_name = "SESSION_NAME"
  }
}

声明多个 AWS 提供者

到目前为止,您已经学会了如何在 Terraform 中声明和配置与单个区域配合使用的 AWS 提供者。但是,如果您需要在多个云区域管理基础设施或 AWS 服务,那么您将需要声明关键字 alias

别名允许为同一提供者定义多个配置,并选择在每个资源或每个模块基础上使用哪个配置或支持多个区域。

下面的代码声明了名为 aws 的默认 AWS 提供者,其中 region 设置为 us-east-2。然后声明了另一个具有相同名称的 AWS 提供者,但带有一个声明的 alias 名称 west 和一个 region 设置为 us-west-2

聲明alias允許您默認在us-east-2區域或者在us-west-2區域(如果選擇提供者aws.west)創建資源,根據需求。

# 默認提供者配置資源開頭為aws。
provider "aws" {
  # 声明名為'aws'的AWS提供者的us-east-2區域
  region = "us-east-2" 
}

# 用於west區域的附加提供者配置。
# 資源可以引用為aws.west。
provider "aws" {
  alias  = "west"
  # 声明名為'west'的AWS提供者的us-west-2區域
  region = "us-west-2"
}

# 在west區域使用附加提供者來聲明資源
resource "aws_instance" "west-region" {
  # 將提供者聲明為aws.west
  # aws.west是從名為'aws'的AWS提供者引用的並且別名為'west'
  provider = aws.west
}

# 使用默認提供者來聲明資源
resource "aws_instance" "east-region" 
}

自定義AWS提供者的終端點配置

自定義終端點配置在連接到非默認AWS服務終點(如AWS Snowball)或進行本地測試時非常方便。

將Terraform AWS提供者配置為使用自定義端點。通過在提供者的塊內聲明endpoints配置塊來實現,如下所示。

下面的配置允許您在本地端口4572訪問AWS S3服務,就如同您實際上在一個AWS帳戶上訪問AWS S3服務一樣。同樣地,該配置允許您在本地端口4569上訪問dynamodb。DynamoDB是一種NoSQL數據庫服務,提供快速性能與無縫的擴展性。

檢查Terraform AWS提供者允許的自定義端點列表。

# 聲明名為'aws'的AWS提供者
provider "aws" {
  # 聲明端點
  endpoints { 
    # 在本地主機上以端口4569聲明dynamodb
    dynamodb = "<http://localhost:4569>"  
    # 在本地主機上以端口4572聲明S3
    s3 = "<http://localhost:4572>"  
  }
}

添加標籤

之前,您已經了解如何用配置如地區、源位置等聲明AWS提供者。但為了更好地管理您的資源,您需要在提供者級別添加標籤

Tags是由用户定义的键和值组成的标签。当您需要检查AWS帐户中的计费、所有权、自动化、访问控制和许多其他用例时,标签非常方便。

与逐个为所有资源添加标签不同,让我们学习如何在提供程序级别为所有资源添加标签,这将帮助节省大量代码和时间。

下面的代码配置了一个具有在default_tags中定义的标签的AWS提供程序。在提供程序内添加标签的好处是,创建具有此提供程序的任何资源时,指定的标签将自动添加。

# 配置名为 'aws' 的AWS提供程序
provider "aws" {
  # 在提供程序级别添加默认标签Environment和Owner
  default_tags {
    # 声明标签值
    tags = {
      Environment = "Production"
      Owner       = "shanky"
    }
  }
}
# 创建标记为Name=MyVPC的资源 'aws_vpc'
resource "aws_vpc" "myinstance" {
  tags = {
    Name = "MyVPC"
  }
}

忽略标签

在提供程序级别启用标签有助于在整个环境中应用标签。但有时,您需要忽略标签,例如,如果您不希望将默认标签添加到EC2实例,而是应用于AWS帐户中的其他资源。让我们来看看!

下面的代码配置了一个具有在提供程序内定义的ignore_tags的AWS提供程序。使用ignore标签的好处是,当您不希望将默认标签添加到某些资源并应用于AWS帐户中的其他资源时。

在下面的代碼中,當您使用 aws 提供者創建任何資源時,所有資源都將忽略 LastScannedkubernetes.io 標籤。

# 配置名為 aws 的 AWS 提供者
provider "aws" {
	# 忽略 AWS 提供者 (aws) 下所有資源的標籤 key_prefixes 和 key 
  ignore_tags {
    key_prefixes = ["kubernetes.io"]
  }
  ignore_tags {
    keys = ["LastScanned"]
  }
}

創建 AWS S3 存儲桶

到目前為止,您已經學會了如何深入聲明和配置 AWS 提供者的所有知識。但僅聲明 AWS 提供者是無濟於事的,直到您管理 AWS 資源,例如提供 AWS S3 存儲桶或刪除 Ec2 實例等。因此,讓我們學習如何創建 AWS S3 存儲桶!

1. 創建一個名為 ~/terraform-s3-demo 的文件夾,然後將工作目錄更改 (cd) 為該文件夾。~/terraform-s3-demo 文件夾將包含您的配置文件和 Terraform 將創建的所有相關文件。

mkdir ~/terraform-s3-demo
cd ~/terraform-s3-demo

2. 在您喜歡的代碼編輯器中複製並粘貼下面的配置,並將其保存為 main.tf~/terraform-s3-demo 目錄中。

main.tf 文件創建了一些必要的資源:

  • 提供者要求:提供者要求包括本地名稱、源位置和版本約束。
  • 加密金鑰:Amazon S3加密金鑰有助於將S3存儲桶中的所有新對象在存儲時進行加密。使用aws_kms_key在Terraform中創建加密金鑰。
  • 配置AWS提供程序:聲明提供程序名稱(aws)以及區域us-east-2
  • 存儲桶:此Terraform模塊創建名為terraformdemobucket的存儲桶。Terraform無法刪除此存儲桶,因為它包含一個標誌force_destroy

版本控制:在Amazon S3中,版本控制意味著在同一存儲桶中保留對象的多個版本

# 配置名為aws的AWS提供程序
provider "aws" {
# 忽略提供程序aws下所有資源的標籤鍵前綴和鍵。 
  ignore_tags {
    key_prefixes = ["kubernetes.io/"]
  }
  ignore_tags {
    keys = ["LastScanned"]
  }
}

# 聲明提供程序要求
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# 配置區域設置為'us-east-2'的AWS提供程序(aws)
provider "aws" {
  region = "us-east-2"
}

# 授予存儲桶訪問權限
resource "aws_s3_bucket_public_access_block" "publicaccess" {
  bucket = aws_s3_bucket.demobucket.id
  block_public_acls = false
  block_public_policy = false
}

# 創建將加密存儲桶對象的加密金鑰
resource "aws_kms_key" "mykey" {
  deletion_window_in_days = "20"
}

# 創建名為terraformdemobucket的存儲桶
resource "aws_s3_bucket" "demobucket" {
  bucket = terraformdemobucket
  force_destroy = false
  server_side_encryption_configuration {
    rule {
        apply_server_side_encryption_by_default {
        kms_master_key_id = aws_kms_key.mykey.arn
        sse_algorithm = "aws:kms"
      }
    }
  }
  # 在同一存儲桶中保留對象的多個版本
  versioning {
    enabled = true
  }
}

3. 現在,執行以下命令以導航至~\\terraform-s3-demo目錄並啟動Terraform。Terraform初始化插件和提供者,這是與資源一起使用所需的。

Terraform通常使用三個命令的順序terraform initterraform planterraform apply

cd ~\terraform-s3-demo       # 切換到 ~\terraform-s3-demo 目錄
terraform init               # 啟動Terraform
terraform plan               # 確保您的配置語法正確
terraform apply -auto-approve # 提供AWS S3 Bucket

使用Terraform創建AWS EC2實例和IAM用戶

在前一節中,您學會了如何使用AWS提供者的Terraform創建單個對象(AWS S3 Bucket)。但實際上,您可以使用Terraform和AWS提供者創建相同類型的多個對象。

1. 創建名為〜/terraform-ec2-iam-demo的文件夾,然後進入其中

2. 開啟你喜愛的程式碼編輯器,複製/貼上下面的配置,並將檔案另存為main.tf~/terraform-ec2-iam-demo目錄下。

下面的程式碼創建兩個 EC2 實例ec21aec21a,分別使用t2.microt2.medium 實例類型,然後創建四個不同名稱的 IAM 使用者。程式碼中聲明的ami是一個Amazon Machine Image (AMI),它提供啟動實例所需的資訊,例如作業系統的類型、要安裝的軟體等。

你可以使用 Amazon EC2 控制台找到 Linux AMI

# 使用 instance_type t2.micro 和 t2.medium 創建實例
resource "aws_instance" "my-machine" {
# 宣告 AMI
  ami = "ami-0a91cd140a1fc148a"
  for_each  = {
      key1 = "t2.micro"
	    key2 = "t2.medium"
   }
  instance_type  = each.value
	key_name       = each.key
    tags =  {
	   Name  = each.value
	}
}
# 使用四個不同名稱創建 IAM 用戶
resource "aws_iam_user" "accounts" {
  for_each = toset( ["Account1", "Account2", "Account3", "Account4"] )
  name     = each.key
}

3. 接下來,創建另一個文件,將以下代碼復制/粘貼到文件中,並將文件保存為 vars.tf~/terraform-ec2-iam-demo 目錄中。

以下代碼宣告了所有變量,在 main.tf 文件中引用。執行 Terraform 代碼後,變量 tag_ec2 的值將分配給 main.tf 文件中定義的兩個 EC2 實例,其值分別為 ec21aec21b

variable "tag_ec2" {
  type = list(string)
  default = ["ec21a","ec21b"]
}

4. 在 ~/terraform-ec2-iam-demo 目錄中創建另一個 Terraform 配置文件,名為 output.tf,然後將以下代碼復制/粘貼到 output.tf 文件中。

成功執行 terraform apply 命令後,您應該在命令輸出的末尾看到 ${aws_instance.my-machine.*.id}${aws_iam_user.accounts.*.name} 的值。

以下代碼告訴 Terraform 引用 main.tf 配置文件中定義的 aws_instanceaws_iam_user 資源。

output "aws_instance" {
   value = "${aws_instance.my-machine.*.id}"
}
output "aws_iam_user" {
   value = "${aws_iam_user.accounts.*.name}"
}

5. 在~/terraform-ec2-iam-demo目錄中創建一個名為provider.tf的配置文件,並將下面的代碼粘貼到provider.tf文件中。下面的provider.tf定義了Terraform AWS提供程序,以便Terraform知道如何與您在前面步驟中定義的所有AWS資源進行交互。

provider "aws" {
   region = "us-east-2"
 }

6. 現在,運行tree命令來驗證~/terraform-ec2-iam-demo文件夾中包含所有必需的文件。

Showing all the Terraform configuration files required

7. 按順序運行下面的命令來初始化Terraform並創建AWS EC2實例和IAM用戶。

terraform init
terraform plan
terraform apply
Terraform apply command executed successfully.

最後,轉到AWS管理控制台,然後跳轉到AWS EC2服務和IAM控制台。

在以下截圖中,您可以驗證EC2實例和IAM用戶是否存在。

Verifying the two EC2 instances that got created using Terraform
Verifying the four IAM users that got created using Terraform

結論

通過這個終極指南,您現在擁有使用AWS提供程序在Terraform中進行聲明和執行的知識。您還了解了AWS提供程序如何以多種安全方式聲明憑據。

現在,您有哪個AWS服務想要使用AWS提供程序和Terraform進行管理?

Source:
https://adamtheautomator.com/terraform-aws/