ゼロからはじめる Infrastructure as Code ~SIer企業がAWSで⾃社Webサービスを⽴ち上げて2年間運⽤してきた話~ / Infrastructure as code starting from scratch

ゼロからはじめる Infrastructure as Code ~SIer企業がAWSで⾃社Webサービスを⽴ち上げて2年間運⽤してきた話~ / Infrastructure as code starting from scratch

JAWS DAYS 2020のオンライン登壇で使用した発表資料です。

42aecedc4c212563b0f3d72928350b44?s=128

Hironori Yokoyama

March 14, 2020
Tweet

Transcript

  1. JAWS DAYS 2020 ゼロからはじめる Infrastructure as Code ~SIer企業がAWSで⾃社Webサービスを⽴ち上げて2年間運⽤してきた話~ 株式会社システムインテグレータ 製品企画室

    横⼭ 弘典
  2. 横⼭ 弘典 (@yokoyantech) (株)システムインテグレータ TOPSIC開発リーダー コミュニティ JAWS UG Saitama Saitama.rb

    好きなAWSサービス CloudFormation 2
  3. 3

  4. JAWS DAYS 初登壇 4

  5. 本⽇お伝えしたいこと 5

  6. インフラのコード化は簡単になった︕ ぜひ挑戦してみてください 6

  7. (株)システムインテグレータ さいたま市 東証⼀部 創業24年⽬ 事業内容 ⾃社パッケージソフト 企画、開発 カスタマイズ WEBサービス 開発、運営

    7
  8. 8

  9. 9

  10. 10

  11. AtCoder社による問題作成 国内最⼤の競技プログラミングコンテンストの開催企業 11

  12. 本⽇はTOPSICの運⽤で 培った体験談をお伝えします 12

  13. ゼロからはじめる Infrastructure as Code 1. AWS環境を構築する 2. 現状のインフラをコード化する 3. 既存リソースと紐付ける

    4. インフラを成⻑させる 5. 2年間の運⽤で得られたもの 13
  14. 何はともあれ 最初は⼿動で構築 14

  15. 15

  16. 作業ログは⼿順書 みんな⼤好きEXCEL管理 16

  17. 課題 画⾯キャプチャがすぐ古くなる 当時存在しなかった設定項⽬なども いちいち張り替えるのは⾯倒 スマートじゃない 再現性が作業者に依存する 17

  18. その後順調にビジネスが成⻑ 18

  19. プロモーションも兼ねて プログラミングコンテストを開催 19

  20. 20

  21. 21

  22. 絶対成功させるために 専⽤環境を構築することに 22

  23. その他要望 TOPSIC Organizationsと組み合わせて環境毎にアカウントを分けたい staging production TOPSIC のAWS環境を流⽤して新製品を作ることに ビジネスの横展開 23

  24. ゼロから⼿作業で 環境構築やり直しは⾟い 24

  25. そこで Infrastructure as Code (以下、IaC) 25

  26. AWS環境を JSON や YAML で 記述してテンプレート化 構成管理、修正、再利⽤が 容易 テンプレートで作成された リソースをスタックと呼ぶ

    スタック単位でリソース 管理できる 26
  27. ゼロからはじめる Infrastructure as Code 1. AWS環境を構築する 2. 現状のインフラをコード化する 3. 既存リソースと紐付ける

    4. インフラを成⻑させる 5. 2年間の運⽤で得られたもの 27
  28. IaCのメリット 冪等性 インフラのコードレビュー 再利⽤が簡単 全て git で管理できる GitOps 信頼できる唯⼀の情報 源とする

    変更の承認はPull Requestで⾏う 28
  29. とはいえ、 何から始めたらいいのか わからない 29

  30. 私達が最初にやったこと 30

  31. 既存環境からのリバース 31

  32. 32

  33. Cloud Formerとは AWS純正のツール 既存のAWS環境のリソース情報からCloudFormationテンプレート を⾃動で作成してくれるツール AWS CloudFormation スタックで提供されている なぜか8年くらいずっとβ版 33

  34. クラスメソッドさんブログより [レポート]What’s New in AWS CloudFormation #reinvent #DOP408 https://dev.classmethod.jp/cloud/aws/cloud-formation-dop408/ Q:

    永遠にベータのCloudFormerはいつアップデートされるんです か︖ A: よく聞いてくれたね笑 残念ながらCloudFormarがこれからア ップデートされることはありません。サードパーティ製の Former2というWebベースのサービスがあるのですが、これが⾮ 常によくできているのでそれを使ってください。 “ “ 34
  35. 今からIaCやるなら Former2がよさそう 35

  36. 36

  37. Former2とは サードパーティ製のWEBツール AWS JavaScript SDKを使⽤ インフラ全体をスキャンし、リソースのリストを⽣成する AWSアカウント内の既存のリソースからコード出⼒ができる アウトプット形式 CloudFormation Terraform

    Troposphere 37
  38. 事前準備 38

  39. 画⾯起動 https://former2.com/ にアクセス 39

  40. 1.Introduction ブラウザ拡張をインストール Chromeウェブストアを表⽰ ⼀部のAWSサービスでは必要ありませんが、すべてのAWSサ ービスをサポートするには、Former2 Helperブラウザー拡張機 能をインストールする必要があります。 “ “ 40

  41. 2.Credentials ReadOnlyAccess のIAMRole、もしくはIAMユーザを⽤意 41

  42. アクセスキー、シークレットキーを⼊⼒ 42

  43. 3.Parameters 独⾃のCloudFormationのスタックパラメータ設定できる デフォルト値が設定されている場合は、CloudFormationの組み込 み関数 !Ref 、 !Sub で使⽤できる 43

  44. 4.Settings アカウントに対するスキャンなどを⾏う 44

  45. 【実践】 EC2のコードを出⼒する 45

  46. Former2の⼀覧からEC2を選択 46

  47. 検索しても何も表⽰されないときは AWSあるある キーが違う、リージョンが違う 47

  48. 出⼒したいインスタンスを選択 出⼒したいインスタンスにチェックを⼊れて、 Add Selected をク リック 48

  49. ヘッダー部分の Generate ボタンをクリック 49

  50. CloudFormationテンプレートが⾃動⽣成される 50

  51. 関連するリソースを出⼒すれば 現状のインフラをコード化できる 51

  52. ゼロからはじめる Infrastructure as Code 1. AWS環境を構築する 2. 現状のインフラをコード化する 3. 既存リソースと紐付ける

    4. インフラを成⻑させる 5. 2年間の運⽤で得られたもの 52
  53. 既存リソースのイン ポート 新機能 2019年11⽉に発表 ⼿動で作成したリソースと CloudFormationテンプレー トを紐づけることができる 53

  54. 課題 ⼿動で作ったリソースの CloudFormationテンプレートを作るのが⼤変 54

  55. Former2で解決 55

  56. 実践 VPCのコードを出⼒してImport 56

  57. 出⼒したテンプレート例(vpc.yml) AWSTemplateFormatVersion: "2010-09-09" Metadata: Generator: "former2" Description: "" Resources: EC2VPC:

    Type: "AWS::EC2::VPC" Properties: CidrBlock: "10.0.0.0/16" EnableDnsSupport: true EnableDnsHostnames: true InstanceTenancy: "default" Tags: - Key: "Name" Value: "stage" 57
  58. 事前準備 Former2で出⼒したテンプレートに DeletionPolicy: Retain を追加 インポートするなら必須の設定 スタック削除時にリソースを保持する Resources: EC2VPC: Type:

    "AWS::EC2::VPC" DeletionPolicy: Retain # これ Properties: 58
  59. インポート⽅法 マネジメントコンソールからCloudFormationにアクセス スタックの作成をクリック 既存のリソースを使⽤(リソースをインポート) をクリック 59

  60. 1.概要をインポート 次へ をクリック 60

  61. 2.テンプレートの指定 Former2で出⼒したテンプレートをアップロードする vpcのテンプレートをアップロード 61

  62. 3.リソースを識別 既存リソースの VpcId を指定 62

  63. 4.スタックの詳細を指定 任意の名前を⼊⼒ 63

  64. 5.概要をインポート ⼿動で作成したVPCに対するアクションが、 Import になっている ことを確認して、 リソースをインポート をクリックする 64

  65. インポートが成功していることを確認 65

  66. 既存のVPCの確認 VPCダッシュボードを開く タグ タブにて、CloudFormationのタグが付与されるようになる 66

  67. スタックに関連付けたリソースは CloudFormationで変更管理できる 67

  68. 気をつけるべきこと いきなりEC2だけインポートすると、循環参照エラーになる リソースの依存と作成の順番を考慮することが⼤事 あるリソースを作成するためには、そのリソースに関連付けるリ ソースを先に作成しておく必要がある 考え⽅はGUI操作と同じ VPC -> SecurityGroup ->

    EC2 で依存している 68
  69. ゼロからはじめる Infrastructure as Code 1. AWS環境を構築する 2. 現状のインフラをコード化する 3. 既存リソースと紐付ける

    4. インフラを成⻑させる 5. 2年間の運⽤で得られたもの 69
  70. インフラを成⻑させる Former2から出⼒したテンプレートは、良くも悪くも現状がそのま ま反映されている 例) リソース同⼠の ID が固定で埋め込まれている そのままでは再利⽤が難しい スタックが⼤きくなりがち 最初は1つの巨⼤なスタックからスタート

    70
  71. 基本⽅針 AWSのベストプラクティスに従う https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/User practices.html 71

  72. ポイント ⼀つのスタックを⼤きくしすぎない スタックを分割して管理する 作成後ほぼ変更しないもの VPC、Subnet、RouteTable、VPN接続 レイヤー毎に分割 DB層(RDS) Application層(ALB,EC2,SecurityGroup) 72

  73. 【実践】 スタックを分割する 73

  74. スタック1 VPC,Subnet,RouteTable作成 74

  75. 75

  76. [Tips] 複数の環境に対応させる Parameters でスタック実⾏時の引数として受け取り変数化する CloudFormationの組み込み関数 !Sub を使⽤する Parameters: ENV: Type:

    String # 例: "staging" Resources: VPC: Type: 'AWS::EC2::VPC' Properties: Tags: - Key: Name Value: !Sub "${ENV}-vpc" # staging-vpc 76
  77. [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/16 77
  78. [Tips] 作成したリソース名を出⼒する Outputs で出⼒して、クロススタック参照できるようにする 他のスタックから Name を指定すると Value を参照可能 Outputs:

    VPC: Value: !Ref VPC Export: Name: !Sub "${ENV}-VPC" # staging-vpc VPCCIDR: Value: !Ref VPCCIDR # 10.0.0.0/16 Export: Name: !Sub "${ENV}-VPCCIDR" # staging-VPCCIDR 78
  79. スタック2 NAT,VPN作成 79

  80. 80

  81. [Tips] クロススタック参照を使う Outputs: PublicSubnet1c: Value: !Ref PublicSubnet1c Export: Name: !Sub

    "${ENV}-PublicSubnet1c" # staging-PublicSubnet1c Fn::ImportValue 関数で、別スタックから Outputs の Value を参照 Resources: NATGateway1c: Type: AWS::EC2::NatGateway Properties: SubnetId: Fn::ImportValue: !Sub "${ENV}-PublicSubnet1c" # staging-PublicSubnet1c 81
  82. スタック3 DB層の作成 82

  83. 83

  84. [Tips] DBのパラメータもコード化 RDSの設定を容易にする バックアップのポリシー、パラメータグループ、MultiAZ等 rds: Type: 'AWS::RDS::DBInstance' Properties: AllocatedStorage: '20'

    DBInstanceClass: db.t3.micro BackupRetentionPeriod: 14 PreferredBackupWindow: '19:00-19:30' PreferredMaintenanceWindow: 'sun:18:00-sun:18:30' DBInstanceIdentifier: !Sub "${ENV}-db" # Staging-db MultiAZ: true 84
  85. スタック4 Application層の作成 85

  86. 86

  87. [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/bash sudo apt-get update -y sudo apt-get install ruby -y sudo apt-get install wget wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install 87
  88. スタックを分割することで 別環境に再利⽤ できる 88

  89. ゼロからはじめる Infrastructure as Code 1. AWS環境を構築する 2. 現状のインフラをコード化する 3. 既存リソースと紐付ける

    4. インフラを成⻑させる 5. 2年間の運⽤で得られたもの 89
  90. 2年間の運⽤で得られたもの Git にすべてのリソースがあるという安⼼感 変更点の履歴が追えるようになった 属⼈的な作業がPull Requestでレビューできるようになった Excel等の⼿順書を全く作らなくなった 必要な時だけ作って壊すという考え⽅にシフトした これまではもったいないからとりあえず停⽌しておくだった AWSがもっと好きになった

    インフラのコード化は楽しい︕ 90
  91. 本⽇お伝えしたいこと 91

  92. インフラのコード化は簡単になった︕ ぜひ挑戦してみてください 92

  93. 93