Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWSとTerraform初心者が やってみたこと

masa-ita
December 21, 2019

AWSとTerraform初心者が やってみたこと

masa-ita

December 21, 2019
Tweet

More Decks by masa-ita

Other Decks in Technology

Transcript

  1. AWSとTerraform初⼼者が
    やってみたこと
    板垣 正敏@JAWS-UG Niigata
    2019/12/21

    View Slide

  2. ⾃⼰紹介
    • 板垣 正敏
    • 県内IT企業の技術顧問(2020/3まで)
    • 中⼩企業診断⼠
    • ⽇本Rubyの会
    • 新潟オープンソース協会
    • Python機械学習勉強会 in 新潟
    • TensorFlow Users Group
    • @itagakim
    • https://github.com/masa-ita
    • AWS歴 2017年〜

    View Slide

  3. システムの全体像

    View Slide

  4. なんのためのシステムか?
    • 社内でのディープラーニング
    実習のための環境
    • GPUマシンをたくさん⽤意で
    きない
    • GPUインスタンスは使うとき
    だけ起動して、コストを抑え
    たい
    • IPアドレスを意識せずに使い
    たい
    • 当初はGUIコンソールとSSHで
    ⼿作業で構築
    • Dynamic DNSとLet’s Encryptで
    構成
    • 現在はELBとCertificate
    Managerを使⽤

    View Slide

  5. AWS Lambda
    EC2起動・停⽌指⽰
    Amazon API Gateway
    DDNS登録・削除
    Amazon DynamoDB
    Amazon EC2
    Amazon Route 53
    Application Load Balancer
    Amazon CloudWatch
    Amazon Elastic Block Store
    Amazon Elastic File System
    EC2起動・停⽌完了通知
    EC2稼働定期通知
    AWS Identity and Access
    Management
    Generic group
    Event
    (time-based)
    Event
    (event-based)
    Event
    (event-based)
    AWS Certificate Manager
    VPC
    WebHook
    API call
    API call
    API call

    View Slide

  6. 本題:Terraformとは?

    View Slide

  7. Infrastructure AS Code
    • コードとしてのインフラ(構成)
    • 再現・再利⽤性
    • 設定ミス・設定漏れの防⽌
    • GUIによらないドキュメント化
    • バージョン管理

    View Slide

  8. なぜTERRAFORM?
    • AWSならCloudFormationがあるが・・・
    • Azure, GCP, オンプレ(Vmware, Nutanix, etc.):ワークフ
    ローの統⼀
    • https://www.terraform.io/docs/providers/index.html

    View Slide

  9. TERRAFORMのしくみ
    • terraform init
    • terraform validate
    • terraform plan
    • terraform apply .tf
    .tfstate
    .tfplan
    Target System
    terraform
    plan
    terraform
    apply

    View Slide

  10. TERRAFORMのインストール
    • プラットフォームごとにZIPファイルで提供
    • シングルバイナリでパスが通っていればOK
    • MacOSならHomebrewでもインストール可能
    • tfenvでバージョン管理も

    View Slide

  11. 構成例
    Labmdaを⽤いたDynamic DNSの部分のみを紹介

    View Slide

  12. プロバイダ設定
    • クレデンシャルは環境変数か
    awscliの設定ファイルに保存
    すべき
    • バージョンアップでの⾮互換
    を防ぐため、Terraformやプロ
    バイダのバージョン指定が有

    • 右の例では、.tfstateファイル
    をS3バケットに保存している
    (共同作業やリモート参照の
    ため)
    terraform {
    required_version = "0.12.17”
    backend "s3" {
    bucket = "tfstate-terraform-demo”
    key = "network/terraform.tfstate”
    region = "ap-northeast-1”
    }
    }
    provider "aws" {
    version = "~> 2.41”
    region = "ap-northeast-1”
    }

    View Slide

  13. variable "name" {}
    variable "policy" {}
    variable "identifier" {}
    resource "aws_iam_role" "default" {
    name = var.name
    assume_role_policy =
    data.aws_iam_policy_document.assume_role.json
    }
    data "aws_iam_policy_document" "assume_role" {
    statement {
    actions = ["sts:AssumeRole"]
    principals {
    type = "Service”
    identifiers = [var.identifier]
    }
    }
    }
    resource "aws_iam_policy" "default" {
    name = var.name
    policy = var.policy
    }
    resource "aws_iam_role_policy_attachment" "default" {
    role = aws_iam_role.default.name
    policy_arn = aws_iam_policy.default.arn
    }
    output "iam_role_arn" {
    value = aws_iam_role.default.arn
    }
    output "iam_role_name" {
    value = aws_iam_role.default.name
    }
    IAM設定⽤モジュール定義

    View Slide

  14. data "aws_iam_policy_document" "for_ddns_lambda" {
    statement {
    effect = "Allow”
    actions = ["ec2:Describe*"]
    resources = ["*"]
    }
    statement {
    effect = "Allow”
    actions = ["dynamodb:*"]
    resources = ["*"]
    }
    statement {
    effect = "Allow”
    actions = [
    "logs:CreateLogGroup",
    "logs:CreateLogStream",
    "logs:PutLogEvents”
    ]
    resources = ["*"]
    }
    statement {
    effect = "Allow”
    actions = ["route53:*"]
    resources = ["*"]
    }
    }
    module "role_for_ddns_lambda" {
    source = "./iam_role”
    name = "role_for_ddns_lambda”
    identifier = "lambda.amazonaws.com”
    policy = data.aws_iam_policy_document.for_ddns_lambda.json
    }
    Lambda関数⽤IAM定義

    View Slide

  15. data "archive_file" "lambda_function" {
    type = "zip”
    source_dir = "lambda/function”
    output_path = "lambda/upload/lambda_function.zip”
    }
    resource "aws_lambda_function" "ddns_lambda" {
    filename = data.archive_file.lambda_function.output_path
    function_name = "ddns_lambda”
    role = module.role_for_ddns_lambda.iam_role_arn
    handler = "union.lambda_handler”
    source_code_hash = data.archive_file.lambda_function.output_base64sha256
    runtime = "python2.7”
    memory_size = 128
    timeout = 120
    }
    resource "aws_lambda_permission" "allow_cloudwatch" {
    statement_id = "AllowExecutionFromCloudWatch”
    action = "lambda:InvokeFunction”
    function_name = aws_lambda_function.ddns_lambda.function_name
    principal = "events.amazonaws.com”
    source_arn = aws_cloudwatch_event_rule.ec2_lambda_ddns_rule.arn
    }
    Lambda関数定義

    View Slide

  16. resource "aws_vpc" "main" {
    cidr_block = "10.0.0.0/16”
    enable_dns_support = true
    enable_dns_hostnames = true
    tags = {
    Name = "main”
    }
    }
    resource "aws_subnet" "main" {
    vpc_id = aws_vpc.main.id
    cidr_block = "10.0.1.0/24”
    map_public_ip_on_launch = true
    availability_zone = "ap-northeast-1d”
    tags = {
    Name = "main”
    }
    }
    resource "aws_internet_gateway" "gw" {
    vpc_id = aws_vpc.main.id
    tags = {
    Name = "main”
    }
    }
    resource "aws_route_table" "public" {
    vpc_id = aws_vpc.main.id
    }
    resource "aws_route" "public" {
    route_table_id = aws_route_table.public.id
    gateway_id = aws_internet_gateway.gw.id
    destination_cidr_block = "0.0.0.0/0”
    }
    resource "aws_route_table_association" "public" {
    subnet_id = aws_subnet.main.id
    route_table_id = aws_route_table.public.id
    }
    resource "aws_vpc_dhcp_options" "aws_subdomain" {
    domain_name = "aws.rails.to”
    domain_name_servers = ["AmazonProvidedDNS"]
    tags = {
    Name = "aws_subdomain”
    }
    }
    output "vpc_id" {
    value = aws_vpc.main.id
    }
    output "main_subnet_id" {
    value = aws_subnet.main.id
    }
    VPC定義

    View Slide

  17. variable "name" {}
    variable "vpc_id" {}
    variable "port" {}
    variable "cidr_blocks" {
    type = list(string)
    }
    resource "aws_security_group" "default" {
    name = var.name
    vpc_id = var.vpc_id
    }
    resource "aws_security_group_rule" "ingress" {
    type = "ingress”
    from_port = var.port
    to_port = var.port
    protocol = "tcp”
    cidr_blocks = var.cidr_blocks
    security_group_id =
    aws_security_group.default.id
    }
    resource "aws_security_group_rule" "egress" {
    type = "egress”
    from_port = 0
    to_port = 0
    protocol = "-1”
    cidr_blocks = ["0.0.0.0/0"]
    security_group_id =
    aws_security_group.default.id
    }
    output "security_group_id" {
    value = aws_security_group.default.id
    }
    Security Group定義⽤モジュール

    View Slide

  18. module "web_server_sg" {
    source = "./security_group”
    name = "web-sg”
    vpc_id = data.terraform_remote_state.network.outputs.vpc_id
    port = 80
    cidr_blocks = ["0.0.0.0/0"]
    }
    resource "aws_instance" "web" {
    ami = "ami-0c3fd0f5d33134a76”
    instance_type = "t3.nano”
    vpc_security_group_ids = [module.web_server_sg.security_group_id]
    subnet_id = data.terraform_remote_state.network.outputs.main_subnet_id
    user_data = <#!/bin/bash
    yum install -y httpd
    systemctl start httpd.service
    EOF
    tags = {
    ZONE = "aws.rails.to.”
    CNAME = "web.aws.rails.to.”
    }
    }
    Security Group と EC2 インスタンスの定義

    View Slide

  19. まとめ

    View Slide

  20. Terraform は強⼒なツール
    • 何よりも構成の再現性がありがたい
    • GUIが時々変わるクラウドには必須のツールか
    • プロビジョニングの機能はそれほど便利ではない(ファイル
    コピーとコマンド実⾏)
    • モジュールの使い⽅(使いどころ)がよくわかってません
    • 最適なリソース分割やディレクトリ配置がまだわかってませ

    View Slide

  21. 参考図書
    • 「実践Terraform」野村友規著
    • オンデマンド / Kindle
    • https://www.amazon.co.jp/dp/4844378139

    View Slide

  22. 参照サイト
    • Terraform Documentation
    • https://www.terraform.io/docs/index.html
    • Lamdaを⽤いたDynamic DNSの参考事例
    • https://aws.amazon.com/jp/blogs/compute/building-a-dynamic-dns-for-
    route-53-using-cloudwatch-events-and-lambda/
    • https://github.com/aws-samples/aws-lambda-ddns-function

    View Slide

  23. おまけ:
    Python機械学習勉強会 in 新潟 Restart #10 やり
    ます
    • 2020年1⽉11⽇(⼟)
    • 新潟市中央公⺠館(クロスパル)
    • 「(仮)ディープラーニングで芸術はできるか?〜⽣成系ネッ
    トワークの進展〜」(itagakim)
    • 「機械学習による動作認識」(Oh!No!さん)
    • 「産学連携セミナー報告とインフラWG設⽴の提案」
    (haru_fujitaさん)
    • 「Deep Learningを⽤いた残存⻭の⾃動認識」(historoidさん)

    View Slide