AnsibleでAWS操作 CloudFrontディストリビューション編

AnsibleでAWS操作シリーズ

  1. aws-cliインストール編
  2. EC2インスタンス編
  3. S3バケット編
  4. CloudFrontディストリビューション編

関連記事

aws-cli コマンド一覧(随時追記)

やりたかったこと

  • CloudFrontディストリビューションの作成
  • S3バケットとの連携
  • GUIを使わずに黒い画面でコマンドを「ッターーン!」してかっこつけたい

やったこと

前提

  • CIサーバー(ansible実行サーバー)構築済み
  • CLIサーバー(aws-cli実行サーバー)構築済み
  • Ansibleインストール済み
  • aws-cliインストール済み
  • 各サーバーへのSSH接続設定済み

${~}は各環境に合わせて値を設定してください。

作業フロー

1. CloudFrontディストリビューションを新規作成

command
ansible-playbook -i inventory/production create-aws-cf-distribution.yml

ディレクトリ構成


├── ansible.cfg
├── create-aws-cf-distribution.yml
├── files
│   └── production
│       └── cf
│           └── distribution.json
├── inventory
│   └── production
│       └── inventory
├── roles
│   └── create-aws-cf-distribution
│       └── tasks
│           └── main.yml
└── vars
    └── all.yml

Ansible構成ファイル

inventory

inventory/production/inventory
[ciservers]
${CIサーバーホスト}

[cliservers]
${CLIサーバーホスト}

[all:vars]
ENV=production

vars

vars/all.yml
AWS:
  S3:
    BUCKET:
      NAME: ${バケット名}

files

files/production/cf/distribution.json
{
  "Id": "",
  "IfMatch": "",
  "DistributionConfig": {
    "Comment": "For S3 Bucket.",
    "CacheBehaviors": {
      "Quantity": 0
    },
    "IsIPV6Enabled": true,
    "Logging": {
      "Bucket": "",
      "Prefix": "",
      "Enabled": false,
      "IncludeCookies": false
    },
    "WebACLId": "",
    "Origins": {
      "Items": [
        {
          "S3OriginConfig": {
            "OriginAccessIdentity": ""
          },
          "OriginPath": "",
          "CustomHeaders": {
            "Quantity": 0
          },
          "Id": "${一意となるID ※1}",
          "DomainName": "${S3バケットの静的サイトホスティングのエンドポイント}"
        }
      ],
      "Quantity": 1
    },
    "DefaultRootObject": "index.html",
    "PriceClass": "PriceClass_All",
    "Enabled": true,
    "DefaultCacheBehavior": {
      "TrustedSigners": {
        "Enabled": false,
        "Quantity": 0
      },
      "LambdaFunctionAssociations": {
        "Quantity": 0
      },
      "TargetOriginId": "${※1で指定したID}",
      "ViewerProtocolPolicy": "allow-all",
      "ForwardedValues": {
        "Headers": {
          "Quantity": 0
        },
        "Cookies": {
          "Forward": "all"
        },
        "QueryStringCacheKeys": {
          "Quantity": 0
        },
        "QueryString": true
      },
      "MaxTTL": ${最大有効TTL},
      "SmoothStreaming": false,
      "DefaultTTL": ${デフォルトTTL},
      "AllowedMethods": {
        "Items": [
          "HEAD",
          "GET"
        ],
        "CachedMethods": {
          "Items": [
            "HEAD",
            "GET"
          ],
          "Quantity": 2
        },
        "Quantity": 2
      },
      "MinTTL": ${最小TTL},
      "Compress": false
    },
    "CallerReference": "${一意となる文字列}",
    "ViewerCertificate": {
      "CloudFrontDefaultCertificate": true,
      "MinimumProtocolVersion": "SSLv3",
      "CertificateSource": "cloudfront"
    },
    "CustomErrorResponses": {
      "Quantity": 0
    },
    "HttpVersion": "http2",
    "Restrictions": {
      "GeoRestriction": {
        "RestrictionType": "none",
        "Quantity": 0
      }
    },
    "Aliases": {
      "Items": [
        "${割り当てたいドメイン ※Route53にて紐付ける際に利用}"
      ],
      "Quantity": 1
    }
  }
}

playbook

create-aws-cf-distribution
- hosts: cliservers
  roles:
    - create-aws-cf-distribution
  vars_files:
    - vars/all.yml

tasks

role/create-aws-cf-distribution/tasks/main.yml
- name: Create Distribution
  shell: |
    aws cloudfront create-distribution \
    --cli-input-json file://files/{{ ENV }}/cf/distribution.json
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always

終わりに

これで、S3バケットをCloudFront経由で表示することが可能になります。
キャッシュを有効利用出来るので、 表示スピードが上がりストレスフリー なページを構築出来ます。

設定用のJsonが少し複雑なので、本記事のJsonをベースに調べながらカスタマイズしてもらえればなと思います。

ただ、このままだとCloudFrontのTTLが効いているのでオブジェクトを更新しても 即時反映 がされません。
また、URLについても、 xxxx.cloudfront.net のようなドメインになっています。

前者については、AWS LambdaによってオブジェクトがPutされたことをトリガーにInvalidationをかけることで解決可能です。(毎回手動でやるのは 運用コスト がかかるので自動化をお勧めします)

後者については、Route53を設定することで独自ドメインによるアクセスが可能になります。

上記の作業についても、aws-cliからの動作確認は済んでいるので時間があるときに記事にまとめようと思っています♪

じゃあの。

続きを読む