Slide 1

Slide 1 text

⼤澤 秀⼀ R&DにおけるTerraformとAnsibleを活⽤した Infrastructure as Codeへの取り組み STAGE 3 研究開発部 Arc Group Architect Team SESSION TAG

Slide 2

Slide 2 text

技術本部 DSOC 研究開発部 Arc Group Architect Team R&D DevOps エンジニア インフラエンジニアから異動、元クラウドコスト最適化おじさん Keyword: AWS/GCP/コスト最適化/Terraform/Ansible/データ基盤 ⼤澤 秀⼀ @ohsawa0515 https://blog.jicoman.info/about Blog:

Slide 3

Slide 3 text

アジェンダ - R&D Arc Group Architect Teamについて - ⾃動化への課題 - Terraformの導⼊と事例 - Ansibleの導⼊と事例 - TerraformとAnsibleの使い分け - まとめ・今後にむけて

Slide 4

Slide 4 text

- 研究員 - 実装したアルゴリズムや機械学習モデルを可能な限り早くサービスインし、 フィードバックを⼊れながら改善したい - エンジニアリング部分に注⼒するのが難しい - R&D DevOps エンジニア - ミッション:R&Dの提供サービスに責任を持つ - ⾼い可⽤性、信頼性、保守性を持った堅牢なサービスとして提供する - 品質を保証しながら研究員ができる領域を増やす R&D Arc Group Architect Teamについて 研究開発部を Drive する

Slide 5

Slide 5 text

- インフラ:AWS/GCP - サーバ:Ubuntu Server、Windows Server - 監視:Datadog、Opsgenie - CI/CD:GitHub Actions、CircleCI - 構成管理:Terraform、CloudFormation、SAM、Chalice、Ansible - バックエンド(API):Python(FastAPI)、C#(ASP.NET Core) - フロントエンド:Vue.js(Nuxt.js) - 管理:GitHub、Jira R&D Arc Group Architect Teamについて 使⽤する技術

Slide 6

Slide 6 text

- アーキテクチャ設計、監視、運⽤ - 設計・実装のコードレビュー - 研究開発部の開発⽣産性の向上 - 開発 - 他チーム、他部署エンジニアとのコミュニケーション - システム連携やAPI設計など研究員と⼀緒に決めていく - インフラについては、インフラグループが担っているので仲介として相談・依頼 R&D Arc Group Architect Teamについて 主なタスク

Slide 7

Slide 7 text

AWSリソース (EC2、IAM Role etc) R&D Arc Group Architect Teamについて 従来のAWSリソース作成の流れ IAMロール/EC2インスタンス が欲しい インフラG (AWSマネジメントコンソール) セキュリティ設定 Active Directoryドメイン参加 Python ミドルウェア etc 依頼者 依頼 AWSリソースの 作成 ヒアリング 作成 完了報告 コマンド実⾏ (SSH)

Slide 8

Slide 8 text

- リードタイムの発⽣ - インフラグループの⼈的リソースに影響されやすい - サービスが増えてくるなかで依頼数も増えてきている R&D Arc Group Architect Teamについて R&D側の課題 - 変更の度に依頼する必要がある - AWS IAMの権限を最⼩にしなければならないが、トライアンドエラーで権限を絞る必要がある - IAMロールの権限不⾜や、新しいAWSサービスを使う度に依頼しなければならない - 対応までに時間がかかる状況ではFullAccessポリシーをアタッチしがち

Slide 9

Slide 9 text

- IAM権限拡⼤への懸念 - IAMに関する権限を渡すと、必要以上に強い権限をもったIAMロール/ポリシーが 作成できるので、セキュリティ上の事故につながりやすい R&D Arc Group Architect Teamについて インフラグループ側の課題 > Amazon Linuxに特化、Chefレシピが秘伝のタレ化してUbuntu Server、 Windows Serverに対応するのが⼤変 > Chefを実⾏するために、対象インスタンスにRubyとGemをインストールする 必要があるが、アプリケーションに関係ないパッケージを⼊れたくない - EC2インスタンスの⼿動プロビジョニング - 元々ChefというツールでEC2インスタンスの作成とプロビジョニングをしていた - GEES(名刺⼊⼒システム)サーバ向けなのでR&D⽤途に対応するのが⼀苦労

Slide 10

Slide 10 text

- EC2インスタンスのプロビジョニングを楽にしたい - [R&D] ⾃分たちで作成できるようにしたい - [Infra] ⾃動化したい - AWSの権限委譲 - [R&D] AWSリソースを “ある程度” ⾃由に作成したい - [Infra] 任せたいが権限を過剰に渡したくない - [R&D, Infra] コード化、GitHub管理、レビューにインフラGを⼊れる R&D Arc Group Architect Teamについて R&Dとインフラグループの課題 Terraform + IAM Permission Boundary Ansible

Slide 11

Slide 11 text

Terraformの導⼊と事例 Terraformとは - HashiCorp社が開発しているオープンソースのIaCツール - HCL(HashiCorp Configuration Language)という独⾃⾔語で記述 - 宣⾔型 - 各クラウドベンダーがプロバイダという形で対応 - AWS/GCP/Azure/Kubernetes/Oracle Cloud Infrastructure/Alibaba Cloud - Datadogに対応。監視設定のコード化に利⽤している

Slide 12

Slide 12 text

Terraformの始め⽅ - Terraformに詳しい⼈がいたのでキャッチアップできた - 最初はIAMロールの作成から - IAMロールの追加や変更は、すでにあるものと同じようにつくっていけば良い - 他のAWSリソースもTerraform化 - リソースを作成するときにドキュメントの⾒⽅を教わって少しずつ範囲を広げた - チーム内でTerraformが浸透し、基本的にTerraformでリソース作成するようになった - 最初からTerraform化するのが難しい場合は、マネジメントコンソール上で作成してから terraform importすることもある Terraformの導⼊と事例

Slide 13

Slide 13 text

- IAM Permissions Boundaryを利⽤ - アクセス権限の境界を設定できる機能 - IAMユーザに対してIAMロール作成権限が付与 されても、境界を超えた権限をIAMロールに付 与することができない IAMロール/ポリシー作成の権限委譲 resource "aws_iam_role" "bar_role" { name = "randd-hogehoge-role" assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json permissions_boundary = "arn:aws:iam::${var.aws_account_id}:policy/Randd_PermissionsBoundary" } IAMユーザの権限 PermissionBoundary に付与された権限 (例: IAMロール作成) 実際に許可される権限の範囲 Terraformの導⼊と事例

Slide 14

Slide 14 text

- ⼀つのGitHubリポジトリにサービス単位でモジュール化 - 各環境でリソースを共通化しつつ、特定の環境のみ設定を変更できる - 例:本番環境のみ IPアドレス制限をする、監査ログを設定する - 影響範囲を⼩さく、素早く変更できる - モジュールをサービス間で共有しない - 共通化の罠にハマりにくい - サービス毎に微妙に異なる設定にしたい場合に条件分岐しなくて済む モジュールによるディレクトリ構成 service_A ├── production │ └── main.tf ├── staging │ └── main.tf ├── dev │ └── main.tf ├── modules │ ├── cloudwatch_logs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── ecs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── elb │ ├── main.tf │ ├── outputs.tf │ └── variables.tf service_B ├── production … Terraformの導⼊と事例

Slide 15

Slide 15 text

- GitHub Pull Request作成時に、GitHub Actionsでterraform fmt、terraform plan - マージ先ブランチとPRブランチでgit diffを取り、差分があったファイル名⼀覧を取得 - ファイル名から2階層⽬までのディレクトリを抽出 - 例:service_A/production/main.tf => service_A/production - main.tfのrequired_versionからTerraformのバージョンを取得 - GitHub Actionsのmatrixに定義しているディレクトリに⼀致している場合にCI実⾏ ディレクトリ単位でCI実⾏ Terraformの導⼊と事例

Slide 16

Slide 16 text

- AWSリソースを作成できることでリードタイムの短縮、インフラGの運⽤負担軽減 - 必要に応じてインフラGをレビュワーに⼊れることで設定ミスによる事故防⽌ - AWS環境への変更履歴や意図を後から追跡できる - なんで変更したんだっけ?の理由がわかる - ⼀つのリポジトリに集約することのメリット - 他のチームがつかうサービスや設定が知ることができる - R&Dが提供しているサービス⼀覧がだいたいわかる 導⼊してよかったこと Terraformの導⼊と事例

Slide 17

Slide 17 text

困ったこと (※) https://github.com/hashicorp/terraform-provider-aws/issues/12923 - AWSプロバイダが最新アップデートに追いついていない場合がある - バグがあってIssueに上がっていても改善されないことがある(マージされない場合が ある) - AWS Lambdaのバージョニング・エイリアスにバグがあった(※) - ドキュメント通りの設定を⾏うとapply⾃体は成功するが、その後にterraform planをすると 403を返してしまうので、ドキュメントとは異なる⽅法で回避 Terraformの導⼊と事例

Slide 18

Slide 18 text

- Red Hat社が開発しているオープンソースの構成管理ツール - エージェントレス - SSH、WinRM(Windowsの場合)接続を介して作業を実⾏ - AWS Systems ManagerセッションマネージャでSSHポートが閉じても実⾏可能 Ansibleの導⼊と事例 Ansibleとは --- - name: Install Apache package: name: "apache2" state: present when: ansible_distribution == 'Ubuntu' - name: Start Apache service: name: apache2 state: started enabled: yes - YAMLファイルで設定を記述 - 複雑なことができないが、 シンプルかつ可読性が上がる - 設定ファイルには “あるべき姿” を記述

Slide 19

Slide 19 text

- Ubuntu Server 20.04 LTS、Deep Learning AMI(18.04 LTS)に対応 - ansible-playbook コマンドでEC2インスタンスの作成からプロビジョニングまで - Canonical社提供の公式AMIを使⽤ - デフォルトパラメータはグループ変数、-eオプションで上書き - EC2インスタンスタイプやEBSボリュームサイズなど - サブネットを複数指定の場合はランダムにサブネットを決定(特定のAZに偏らせないように) Ansibleの導⼊と事例 Ansibleで簡単プロビジョニング ansible-playbook ¥ -i inventory/aws-production/production.aws_ec2.yml ¥ playbooks/aws_ec2_initial_setup.yml ¥ --private-key /home/ansible/.ssh/key_pair.pem ¥ -e "target_hosts=foo_server" ¥ -e "ec2_instance_type=m5.xlarge" ¥ -e "ec2_volume_size=100"

Slide 20

Slide 20 text

- 静的インベントリ: ホスト情報をYAMLファイルで直接記載して管理 - 動的インベントリ: EC2 APIやメタデータでEC2インスタンス情報を 取得してホスト管理 - AWSのようなクラウド環境では EC2インスタンスの状況は常に変わり続けている 動的インベントリへの対応 plugin: aws_ec2 regions: - ap-northeast-1 # グルーピングの設定 # Appタグ単位でグルーピング keyed_groups: - key: tags.App separator: "_" # inventory_hostnameの設定項⽬の優先順位 # Nameが無ければプライベートIPv4アドレスを採⽤ hostnames: - tag:Name - private-ip-address compose: # ansible_hostをプライベートIPv4アドレスに変更する ansible_host: private_ip_address Ansibleの導⼊と事例

Slide 21

Slide 21 text

- Inventoryディレクトリには AWS/GCP各環境のグループ変数ファイルと インベントリファイルを格納 - playbookディレクトリにはPlaybookファイル - 実⾏サーバに対する作業内容を定義したファイル - 実際の処理はrolesディレクトリ以下に ロール単位で分割 - Playbookで再利⽤できるように ディレクトリ構成 ├── ansible.cfg ├── inventory │ ├── aws-production │ │ ├── production.aws_ec2.yml │ │ └── group_vars │ ├── aws-staging │ ├── aws-dev │ ├── gcp-dev │ └── gcp-production ├── playbooks │ └── install_hogehoge.yml ├── requirements.yml └── roles ├── common │ └── locale │ ... ├── gui └── web Ansibleの導⼊と事例

Slide 22

Slide 22 text

- Visual Studio Code(VSCode) Remote Container(Dockerコンテナ上)で開発 - ローカル環境に依存しない - Ansibleのバージョンを固定化 - 環境構築時にVSCodeの拡張機能をインストール できる(ansibleシンタックス/補完など) - GitHub Pull Request作成時にGitHub Actionsでansible-lintを実⾏ Playbook/Roleの開発・テスト Ansibleの導⼊と事例

Slide 23

Slide 23 text

Terraform TerraformとAnsibleの使い分け クラウドのインフラコード化 サーバのセットアップ、サーバ内の処理実⾏ - IaCツール - 宣⾔型 - 記述する順序が実⾏に影響しない - 冪等性 - ステートフル - tfstateファイルで状態管理 - コード上の設定を削除、 Applyしたときにtfstateと現状のリソース 状況の差分を⾒てリソースが削除される - AWSプロバイダは 数⽇おきにリリースされている Ansible - 構成管理ツール - 宣⾔型 + ⼿続き型 - Ansibleモジュール単体は宣⾔型・冪等性が多い - Shellモジュールは冪等性を保つように書く必要がある - 上から順に実⾏されていく - ステートレス - コード上で設定を削除、実⾏してもリソースは残る - リソースを削除する処理を書く必要がある - AWSモジュールの開発が遅く、サポートされていない サービスが多い

Slide 24

Slide 24 text

- インフラCIの整備 - Ansible Moleculeを利⽤してEC2インスタンスにPlaybook単位のテスト実⾏ - SSHからSystems Managerセッションマネージャへの変更 - キーペアの管理不要 - Slackボット化 - ローカル(VSCode)環境からのPlaybook実⾏をやめる まとめ・今後にむけて Ansible実⾏環境の改善

Slide 25

Slide 25 text

研究開発部 Arc Group Architect Team Twitter @ohsawa0515 Eight Virtual Card ⼤澤 秀⼀ 8card.net/p/ shuichi_ohsawa