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

# AnsibleでAWS操作シリーズ

1. [aws-cliインストール編](http://qiita.com/bakira/items/d94fc79a032b117bf87f)
1. [EC2インスタンス編](http://qiita.com/bakira/items/ae56e8e03eed4dc75a01)
1. [S3バケット編](http://qiita.com/bakira/items/a1dfe79cfd0e3acaa1a6)
1. CloudFrontディストリビューション編
1. [Simple Email Service編](http://qiita.com/bakira/items/8147fcc7cb684beedc63)
1. [Certificate Manager編](http://qiita.com/bakira/items/50bdd853ce71953e1600)
1. [Lambda編](https://qiita.com/bakira/items/d55c91328cd1f0ee9581)

# 関連記事

[aws-cli　コマンド一覧(随時追記)](http://qiita.com/bakira/items/8a9481c99ed56a367415)

# やりたかったこと

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

# やったこと

## 前提

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

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

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

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

## ディレクトリ構成
```text

├── 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

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

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

[all:vars]
ENV=production

```

### vars

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

### files

```json: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　※１}",
          "DomainName": "${S3バケットの静的サイトホスティングのエンドポイント}"
        }
      ],
      "Quantity": 1
    },
    "DefaultRootObject": "index.html",
    "PriceClass": "PriceClass_All",
    "Enabled": true,
    "DefaultCacheBehavior": {
      "TrustedSigners": {
        "Enabled": false,
        "Quantity": 0
      },
      "LambdaFunctionAssociations": {
        "Quantity": 0
      },
      "TargetOriginId": "${※１で指定した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

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

### tasks

```yaml: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からの動作確認は済んでいるので時間があるときに記事にまとめようと思っています♪

じゃあの。