タイトル通りですが、今回のお題は『パラメータ→構築自動化』です。
イメージとしては、 ・PowerShellスクリプト叩く ・CSVからパラメータ読み込む、 ・CFnのテンプレ(JSON)にパラメータを渡し、スタック作成。 という感じです。
先ずは簡単なところから…ということで、VPC~Subnetの作成までを行ってみます。 構成はVPC内にPublicなSubnet×2(マルチAZ)というシンプルなもの。
因みに、"AWS Tools for PowerShell"を使用していますが初期設定は割愛しています。
目次
- 1. CloudFormationテンプレートファイル作成
- 2. CSVファイルの準備
- 3. PowerShellスクリプト作成
- 4. スクリプト実行
- 5. スタックの状態確認
- 6. リソースの確認
CloudFormationテンプレートファイル作成
はじめにCFnのテンプレートファイルを作成します。 今回はVPCとSubnet作成用に2ファイル用意。(見やすいという理由で) "Parameters"ブロックで受け取る引数を指定、 "Resources"ブロック内で作成するリソースに関する記述を行っています。
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"vpccidrblock": {
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"Default": "172.31.0.0/16",
"Type": "String"
},
"vpcname":{
"Type": "String"
}
},
"Resources": {
"VPC": {
"Properties": {
"CidrBlock": {
"Ref": "vpccidrblock"
},
"Tags": [
{
"Key": "Application",
"Value": {
"Ref": "AWS::StackId"
}
},
{
"Key": "Name",
"Value": {
"Ref": "vpcname"
}
}
]
},
"Type": "AWS::EC2::VPC"
}
}
}
Subnet作成用JSONファイル(subnettest.json)
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"subnetname": {
"Type": "String"
},
"subnetcidrblock": {
"Type": "String"
},
"subnetazname": {
"Type": "AWS::EC2::AvailabilityZone::Name"
},
"subnetpublicipflag": {
"Type": "String"
},
"vpcid": {
"Type": "String"
}
},
"Resources": {
"Subnet": {
"Properties": {
"CidrBlock": {
"Ref": "subnetcidrblock"
},
"MapPublicIpOnLaunch" : {
"Ref": "subnetpublicipflag"
},
"AvailabilityZone": {
"Ref": "subnetazname"
},
"VpcId" : { "Ref" : "vpcid" },
"Tags": [
{
"Key": "Name",
"Value": {
"Ref": "subnetname"
}
}
]
},
"Type": "AWS::EC2::Subnet"
}
}
}
また、作成したJSONファイルはS3にアップロードしておきます。
ここでは"my-cfn-templates-000"という名前でバケットを作成し、 その中にJSONファイルをアップロードしています。
CSVファイルの準備
特筆するところもないですが、 前項で作成したCFnテンプレに渡す為のパラメータを記述したCSVを用意します。 見づらいので、Excelで開いたものを載せておきます。
"subnetazflag"は、東京リージョンのAZ "ap-northeast-1a"、"ap-northeast-1c"を判別するフラグになります。
また同一VPC内にSubnetを作成することを前提として作成しているので、 2行目はブランクにしています。
PowerShellスクリプト作成
続いて、PowerShellのスクリプトを作成します。 汚いコードですが、以下のような感じに書いてみました。 少し長いので3分割しています。
①変数設定等 Credential等の設定はEC2上から実行するのであれば不要ですね。
#Credentialファイルのパスを指定 $credentials_path = "<任意のパス>" #リージョンの指定(今回は東京リージョン) $aws_region = "ap-northeast-1" #CFnテンプレートファイルを格納したS3のURLを指定 $template_url1 = "https://s3.amazonaws.com/my-cfn-templates-000/vpctest.json" $template_url2 = "https://s3.amazonaws.com/my-cfn-templates-000/subnettest.json" #Credintial、リージョンの設定 Set-AWSCredentials -StoreAs $credentials_path Set-DefaultAWSRegion -Region $aws_Region #CSVファイルの読み込み(デスクトップに配置したparam.csvを指定) $csvfile = Get-ChildItem env:USERPROFILE | % {$_.value} $csvfile += "\Desktop\param.csv" $cfnparam = Get-Content $csvfile | ConvertFrom-Csv -Delimiter ","
②VPC作成処理 スタック名はユニークにする必要があるので注意です。 "vpcname"ですがSubnet作成処理でVPCのidを特定するのに使う為、 スコープを"script"にしています。
#インスタンスを作成し、パラメータを付加 function Create_Object($param_key,$param_value){ $p = New-Object -Type Amazon.CloudFormation.Model.Parameter $p.ParameterKey = $param_key $p.ParameterValue = $param_value return $p } #VPC作成処理 function Create_Vpc{ $stackname = "vpc-stack-00" $script:vpcname = $cfnparam.vpcname $vpccidrblock = $cfnparam.vpccidrblock $p1 = Create_Object vpcname $vpcname $p2 = Create_Object vpccidrblock $vpccidrblock New-CFNStack -StackName $stackname ` -TemplateURL $template_url1 ` -Parameter @( $p1, $p2 ) ` -OnFailure "ROLLBACK" }
③Subnet作成処理、Function実行 CSVファイルを見ればお察しかと思いますが、 "vpcname"パラメータを変数に代入する際、複数行だと当然ながら配列型になってしまう為、 文字列型かそうでないかを判別しています。(無理やり感満載ですが…)
Function実行部分では、"Start-Sleep"にて処理を待つようにしています。 が、入れなくても問題ない?気がしています…。
#Subnet作成処理
function Create_Subnet{
$stack_count = 0
if($vpcname.gettype().fullname -ne [System.String]){
$vpcid = (Get-EC2Tag -region $aws_Region | ? {$_.value -eq $vpcname[0]} | % {$_.resourceid})
}else{
$vpcid = (Get-EC2Tag -region $aws_Region | ? {$_.value -eq $vpcname} | % {$_.resourceid})
}
$avz = Get-EC2AvailabilityZone -region $aws_Region | % {$_.zonename}
foreach ($cfn_param in $cfnparam) {
$stackname = "subnet-stack-" + ("{0:00}" -F $stack_count)
$stack_count ++
$subnetname = $cfn_param.subnetname
$subnetcidrblock = $cfn_param.subnetcidrblock
$subnetazflag = $cfn_param.subnetazflag
$subnetpublicipflag = $cfn_param.subnetpublicipflag
$p3 = Create_Object subnetname $subnetname
$p4 = Create_Object subnetcidrblock $subnetcidrblock
$p5 = Create_Object subnetazname $avz[$subnetazflag]
$p6 = Create_Object subnetpublicipflag $subnetpublicipflag
$p7 = Create_Object vpcid $vpcid
New-CFNStack -StackName $stackname `
-TemplateURL $template_url2 `
-Parameter @( $p3, $p4, $p5, $p6, $p7 ) `
-OnFailure "ROLLBACK"
}
}
Create_Vpc
Start-Sleep -Seconds 60
Create_Subnet
スクリプト実行
前項で作成したスクリプトを叩くだけです…。
スタックの状態確認
マネジメントコンソールから確認してみます。 "CREATE_COMPLETE"となっていれば完了です。
リソースの確認
最後にVPC、Subnetをコマンドで確認してみましょう。 "Get-EC2Vpc"、"Get-EC2Subnet"を使用します。
CSVファイルに入力したパラメータ通り、作成できていることが確認できました。 以上が一連の流れとなります。
EC2の作成は割愛しましたので、中途半端ではありますが如何でしょうか。 頑張れば構築が楽になりそうな気が?しますね…。
また、デフォルトではスタックを削除するとリソースも削除されるのですが オプションにて削除しないようにすることもできます。
JSONファイルの"Resources"ブロックにて "DeletionPolicy" : "Retain"とすることで削除されなくなります。
それでは次の機会に。










