App下載

對(duì)流層簡(jiǎn)介:如何以編程方式創(chuàng)建 Cloudformation 模板

奶味起司 2021-08-24 12:01:04 瀏覽數(shù) (2155)
反饋

我們將首先安裝對(duì)流層庫(kù):

$ pip install troposphere

安裝完成后,您可以創(chuàng)建一個(gè)名為 helloworld-cf-template.py 的新文件。

我們將通過從對(duì)流層模塊導(dǎo)入一些定義來開始我們的文件:


"""Generating CloudFormation template."""

from troposphere import (
  Base64,
  ec2,
  GetAtt,
  Join,
  Output,
  Parameter,
  Ref,
  Template,
)

從代碼的角度來看,我們要做的第一件事是初始化一個(gè)模板變量。在我們的腳本結(jié)束時(shí),模板將包含我們基礎(chǔ)設(shè)施的完整描述,我們將能夠簡(jiǎn)單地打印其輸出以獲取我們的 CloudFromation 模板:

t = Template()

在本書中,我們將同時(shí)創(chuàng)建和運(yùn)行多個(gè) CloudFormation 模板。為了幫助我們識(shí)別給定堆棧中的內(nèi)容,我們可以提供描述。創(chuàng)建模板后,添加如下描述:

t.add_description("Effective DevOps in AWS: HelloWorld web application")

當(dāng)我們使用 Web 命令行界面啟動(dòng) EC2 實(shí)例時(shí),我們選擇了使用哪個(gè)密鑰對(duì)以獲得對(duì)主機(jī)的 SSH 訪問。為了不失去這種能力,我們的模板首先要有一個(gè)參數(shù),它為 CloudFormation 用戶提供在啟動(dòng) EC2 實(shí)例時(shí)選擇要使用的密鑰對(duì)的能力。

為此,我們將創(chuàng)建一個(gè) Parameter 對(duì)象,并通過提供標(biāo)識(shí)符、描述、參數(shù)類型、描述和約束描述來初始化它,以幫助做出正確的決定

當(dāng)我們啟動(dòng)堆棧時(shí)。為了讓這個(gè)參數(shù)存在于我們的最終模板中,我們還將使用模板類中定義的 add_paramter() 函數(shù):

t.add_parameter(Parameter(
   "KeyPair",
   Description="Name of an existing EC2 KeyPair to SSH",
   Type="AWS::EC2::KeyPair::KeyName",
   ConstraintDescription="must be the name of an existing EC2 KeyPair.",
))

接下來我們要看的是安全組。我們將完全按照我們對(duì) KeyPair 參數(shù)所做的那樣進(jìn)行。


ApplicationPort = 3000 

t.add_resource(ec2.SecurityGroup(
   "SecurityGroup",
   GroupDescription="Allow SSH and TCP/{} access".format(ApplicationPort),
   SecurityGroupIngress=[
   ec2.SecurityGroupRule(
     IpProtocol="tcp",
     FromPort="22",
     ToPort="22",
     CidrIp="0.0.0.0/0",
   ),
   ec2.SecurityGroupRule(
     IpProtocol="tcp",
     FromPort=ApplicationPort,
     ToPort=ApplicationPort,
     CidrIp="0.0.0.0/0",
  ),
 ],
))

在下一節(jié)中,我們將不再需要登錄到我們的 EC2 實(shí)例并手動(dòng)安裝 helloworld.js 文件及其初始化腳本。為此,我們將利用 EC2 提供的 UserData 功能。

創(chuàng)建 EC2 實(shí)例時(shí),您可以通過 UserData 可選參數(shù)提供一組命令,以便在虛擬機(jī)啟動(dòng)后運(yùn)行。


user_data = Base64(Join('\n', [
 "#!/bin/bash",
 "sudo yum install --enablerepo=epel -y nodejs",
 "wget http://bit.ly/2vESNuc -O /home/ec2-user/helloworld.js",
 "wget http://bit.ly/2vVvT18 -O /etc/init/helloworld.conf",
 "start helloworld"
]))

我們現(xiàn)在將專注于我們模板的主要資源,我們的 EC2 實(shí)例。創(chuàng)建實(shí)例需要提供用于標(biāo)識(shí)資源的名稱、映像 ID、實(shí)例類型、安全組、用于 SSH 訪問的密鑰對(duì)以及用戶數(shù)據(jù)。

為了簡(jiǎn)單起見,我們將對(duì) AMI ID ( ami-a4c7edb2 ) 和實(shí)例類型 ( t2.micro ) 進(jìn)行硬編碼。

創(chuàng)建我們的 EC2 實(shí)例所需的其余信息是安全組信息和密鑰對(duì)名稱,我們之前通過定義參數(shù)和資源收集了這些信息。在 CloudFormation 中,您可以使用關(guān)鍵字 Ref 來引用模板的預(yù)先存在的小節(jié)。

在對(duì)流層中,這是通過調(diào)用 Ref() 函數(shù)來完成的。和以前一樣,我們將在 add_resource 函數(shù)的幫助下將結(jié)果輸出添加到我們的模板中:

t.add_resource(ec2.Instance(
  "instance",
  ImageId="ami-a4c7edb2",
  InstanceType="t2.micro",
  SecurityGroups=[Ref("SecurityGroup")],
  KeyName=Ref("KeyPair"),
  UserData=user_data,
))

在我們腳本的最后一部分,我們將專注于生成模板的輸出部分,當(dāng) CloudFormation 創(chuàng)建堆棧時(shí),該部分會(huì)被填充。

此選擇允許您打印出在堆棧啟動(dòng)期間計(jì)算的有用信息。在我們的例子中,有兩個(gè)有用的信息,訪問我們的 Web 應(yīng)用程序的 URL 和實(shí)例的公共 IP 地址,以便我們可以根據(jù)需要通過 SSH 訪問它。

為了檢索此類信息,CloudFormation 使用函數(shù) Fn::GetAtt 。在對(duì)流層,這被轉(zhuǎn)換為使用 GetAttr() 函數(shù):


t.add_output(Output(
  "InstancePublicIp",
  Description="Public IP of our instance.",
  Value=GetAtt(instance, "PublicIp"),
))

t.add_output(Output(
  "WebUrl",
  Description="Application endpoint",
  Value=Join("", [
      "http://", GetAtt(instance, "PublicDnsName"), ":", ApplicationPort
  ]),
))

此時(shí),我們可以讓我們的腳本輸出我們生成的模板的最終結(jié)果:

print t.to_json()


0 人點(diǎn)贊