JAWS DAYS 2020のオンライン登壇で使用した発表資料です。
JAWS DAYS 2020ゼロからはじめる Infrastructure as Code~SIer企業がAWSで⾃社Webサービスを⽴ち上げて2年間運⽤してきた話~株式会社システムインテグレータ製品企画室 横⼭ 弘典
View Slide
横⼭ 弘典(@yokoyantech)(株)システムインテグレータTOPSIC開発リーダーコミュニティJAWS UG SaitamaSaitama.rb好きなAWSサービスCloudFormation2
3
JAWS DAYS 初登壇4
本⽇お伝えしたいこと5
インフラのコード化は簡単になった︕ぜひ挑戦してみてください6
(株)システムインテグレータさいたま市東証⼀部創業24年⽬事業内容⾃社パッケージソフト企画、開発カスタマイズWEBサービス開発、運営7
8
9
10
AtCoder社による問題作成国内最⼤の競技プログラミングコンテンストの開催企業11
本⽇はTOPSICの運⽤で培った体験談をお伝えします12
ゼロからはじめる Infrastructure as Code1. AWS環境を構築する2. 現状のインフラをコード化する3. 既存リソースと紐付ける4. インフラを成⻑させる5. 2年間の運⽤で得られたもの13
何はともあれ最初は⼿動で構築14
15
作業ログは⼿順書みんな⼤好きEXCEL管理16
課題画⾯キャプチャがすぐ古くなる当時存在しなかった設定項⽬などもいちいち張り替えるのは⾯倒スマートじゃない再現性が作業者に依存する17
その後順調にビジネスが成⻑18
プロモーションも兼ねてプログラミングコンテストを開催19
20
21
絶対成功させるために専⽤環境を構築することに22
その他要望TOPSICOrganizationsと組み合わせて環境毎にアカウントを分けたいstagingproductionTOPSIC のAWS環境を流⽤して新製品を作ることにビジネスの横展開23
ゼロから⼿作業で環境構築やり直しは⾟い24
そこでInfrastructure as Code(以下、IaC)25
AWS環境を JSON や YAML で記述してテンプレート化構成管理、修正、再利⽤が容易テンプレートで作成されたリソースをスタックと呼ぶスタック単位でリソース管理できる26
ゼロからはじめる Infrastructure as Code1. AWS環境を構築する2. 現状のインフラをコード化する3. 既存リソースと紐付ける4. インフラを成⻑させる5. 2年間の運⽤で得られたもの27
IaCのメリット冪等性インフラのコードレビュー再利⽤が簡単全て git で管理できるGitOps信頼できる唯⼀の情報源とする変更の承認はPullRequestで⾏う28
とはいえ、何から始めたらいいのかわからない29
私達が最初にやったこと30
既存環境からのリバース31
32
Cloud FormerとはAWS純正のツール既存のAWS環境のリソース情報からCloudFormationテンプレートを⾃動で作成してくれるツールAWS CloudFormation スタックで提供されているなぜか8年くらいずっとβ版33
クラスメソッドさんブログより[レポート]What’s New in AWS CloudFormation #reinvent#DOP408https://dev.classmethod.jp/cloud/aws/cloud-formation-dop408/Q: 永遠にベータのCloudFormerはいつアップデートされるんですか︖A: よく聞いてくれたね笑 残念ながらCloudFormarがこれからアップデートされることはありません。サードパーティ製のFormer2というWebベースのサービスがあるのですが、これが⾮常によくできているのでそれを使ってください。““34
今からIaCやるならFormer2がよさそう35
36
Former2とはサードパーティ製のWEBツールAWS JavaScript SDKを使⽤インフラ全体をスキャンし、リソースのリストを⽣成するAWSアカウント内の既存のリソースからコード出⼒ができるアウトプット形式CloudFormationTerraformTroposphere37
事前準備38
画⾯起動https://former2.com/ にアクセス39
1.Introductionブラウザ拡張をインストールChromeウェブストアを表⽰⼀部のAWSサービスでは必要ありませんが、すべてのAWSサービスをサポートするには、Former2 Helperブラウザー拡張機能をインストールする必要があります。““40
2.CredentialsReadOnlyAccess のIAMRole、もしくはIAMユーザを⽤意41
アクセスキー、シークレットキーを⼊⼒42
3.Parameters独⾃のCloudFormationのスタックパラメータ設定できるデフォルト値が設定されている場合は、CloudFormationの組み込み関数 !Ref 、 !Sub で使⽤できる43
4.Settingsアカウントに対するスキャンなどを⾏う44
【実践】EC2のコードを出⼒する45
Former2の⼀覧からEC2を選択46
検索しても何も表⽰されないときはAWSあるあるキーが違う、リージョンが違う47
出⼒したいインスタンスを選択出⼒したいインスタンスにチェックを⼊れて、 Add Selected をクリック48
ヘッダー部分の Generate ボタンをクリック49
CloudFormationテンプレートが⾃動⽣成される50
関連するリソースを出⼒すれば現状のインフラをコード化できる51
ゼロからはじめる Infrastructure as Code1. AWS環境を構築する2. 現状のインフラをコード化する3. 既存リソースと紐付ける4. インフラを成⻑させる5. 2年間の運⽤で得られたもの52
既存リソースのインポート新機能2019年11⽉に発表⼿動で作成したリソースとCloudFormationテンプレートを紐づけることができる53
課題⼿動で作ったリソースのCloudFormationテンプレートを作るのが⼤変54
Former2で解決55
実践VPCのコードを出⼒してImport56
出⼒したテンプレート例(vpc.yml)AWSTemplateFormatVersion: "2010-09-09"Metadata:Generator: "former2"Description: ""Resources:EC2VPC:Type: "AWS::EC2::VPC"Properties:CidrBlock: "10.0.0.0/16"EnableDnsSupport: trueEnableDnsHostnames: trueInstanceTenancy: "default"Tags:-Key: "Name"Value: "stage" 57
事前準備Former2で出⼒したテンプレートに DeletionPolicy: Retain を追加インポートするなら必須の設定スタック削除時にリソースを保持するResources:EC2VPC:Type: "AWS::EC2::VPC"DeletionPolicy: Retain # これProperties:58
インポート⽅法マネジメントコンソールからCloudFormationにアクセススタックの作成をクリック既存のリソースを使⽤(リソースをインポート) をクリック59
1.概要をインポート次へ をクリック60
2.テンプレートの指定Former2で出⼒したテンプレートをアップロードするvpcのテンプレートをアップロード61
3.リソースを識別既存リソースの VpcId を指定62
4.スタックの詳細を指定任意の名前を⼊⼒63
5.概要をインポート⼿動で作成したVPCに対するアクションが、 Import になっていることを確認して、 リソースをインポート をクリックする64
インポートが成功していることを確認65
既存のVPCの確認VPCダッシュボードを開くタグ タブにて、CloudFormationのタグが付与されるようになる66
スタックに関連付けたリソースはCloudFormationで変更管理できる67
気をつけるべきこといきなりEC2だけインポートすると、循環参照エラーになるリソースの依存と作成の順番を考慮することが⼤事あるリソースを作成するためには、そのリソースに関連付けるリソースを先に作成しておく必要がある考え⽅はGUI操作と同じVPC -> SecurityGroup -> EC2 で依存している68
ゼロからはじめる Infrastructure as Code1. AWS環境を構築する2. 現状のインフラをコード化する3. 既存リソースと紐付ける4. インフラを成⻑させる5. 2年間の運⽤で得られたもの69
インフラを成⻑させるFormer2から出⼒したテンプレートは、良くも悪くも現状がそのまま反映されている例)リソース同⼠の ID が固定で埋め込まれているそのままでは再利⽤が難しいスタックが⼤きくなりがち最初は1つの巨⼤なスタックからスタート70
基本⽅針AWSのベストプラクティスに従うhttps://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/Userpractices.html71
ポイント⼀つのスタックを⼤きくしすぎないスタックを分割して管理する作成後ほぼ変更しないものVPC、Subnet、RouteTable、VPN接続レイヤー毎に分割DB層(RDS)Application層(ALB,EC2,SecurityGroup)72
【実践】スタックを分割する73
スタック1VPC,Subnet,RouteTable作成74
75
[Tips] 複数の環境に対応させるParameters でスタック実⾏時の引数として受け取り変数化するCloudFormationの組み込み関数 !Sub を使⽤するParameters:ENV:Type: String # 例: "staging"Resources:VPC:Type: 'AWS::EC2::VPC'Properties:Tags:- Key: NameValue: !Sub "${ENV}-vpc" # staging-vpc76
[Tips] テンプレートに固有のIDをベタ書きしないCloudFormationの組み込み関数 !Ref を使⽤するテンプレート内のリソースの値を返すParameters:VPCCIDR:Type: String # 例: "10.0.0.0/16"Resources:VPC:Type: 'AWS::EC2::VPC'Properties:CidrBlock: !Ref VPCCIDR # 10.0.0.0/1677
[Tips] 作成したリソース名を出⼒するOutputs で出⼒して、クロススタック参照できるようにする他のスタックから Name を指定すると Value を参照可能Outputs:VPC:Value: !Ref VPCExport:Name: !Sub "${ENV}-VPC" # staging-vpcVPCCIDR:Value: !Ref VPCCIDR # 10.0.0.0/16Export:Name: !Sub "${ENV}-VPCCIDR" # staging-VPCCIDR78
スタック2NAT,VPN作成79
80
[Tips] クロススタック参照を使うOutputs:PublicSubnet1c:Value: !Ref PublicSubnet1cExport:Name: !Sub "${ENV}-PublicSubnet1c" # staging-PublicSubnet1cFn::ImportValue 関数で、別スタックから Outputs の Value を参照Resources:NATGateway1c:Type: AWS::EC2::NatGatewayProperties:SubnetId:Fn::ImportValue: !Sub "${ENV}-PublicSubnet1c" # staging-PublicSubnet1c 81
スタック3DB層の作成82
83
[Tips] DBのパラメータもコード化RDSの設定を容易にするバックアップのポリシー、パラメータグループ、MultiAZ等rds:Type: 'AWS::RDS::DBInstance'Properties:AllocatedStorage: '20'DBInstanceClass: db.t3.microBackupRetentionPeriod: 14PreferredBackupWindow: '19:00-19:30'PreferredMaintenanceWindow: 'sun:18:00-sun:18:30'DBInstanceIdentifier: !Sub "${ENV}-db" # Staging-dbMultiAZ: true84
スタック4Application層の作成85
86
[Tips] ⼿動設定が⾯倒なものをコード化EC2のロール設定CodeDeployエージェントのインストールType: 'AWS::IAM::Role'Properties:ManagedPolicyArns:- 'arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole'- 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM'Type: 'AWS::EC2::Instance'Properties:UserData: !Base64 |#! /bin/bashsudo apt-get update -ysudo apt-get install ruby -ysudo apt-get install wgetwget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install87
スタックを分割することで別環境に再利⽤できる88
ゼロからはじめる Infrastructure as Code1. AWS環境を構築する2. 現状のインフラをコード化する3. 既存リソースと紐付ける4. インフラを成⻑させる5. 2年間の運⽤で得られたもの89
2年間の運⽤で得られたものGit にすべてのリソースがあるという安⼼感変更点の履歴が追えるようになった属⼈的な作業がPull RequestでレビューできるようになったExcel等の⼿順書を全く作らなくなった必要な時だけ作って壊すという考え⽅にシフトしたこれまではもったいないからとりあえず停⽌しておくだったAWSがもっと好きになったインフラのコード化は楽しい︕90
本⽇お伝えしたいこと91
インフラのコード化は簡単になった︕ぜひ挑戦してみてください92
93