LoginSignup
3
2

More than 5 years have passed since last update.

AnsibleでAWS操作 Simple Email Service編

Last updated at Posted at 2017-08-21

AnsibleでAWS操作シリーズ

  1. aws-cliインストール編
  2. EC2インスタンス編
  3. S3バケット編
  4. CloudFrontディストリビューション編
  5. Simple Email Service編
  6. Certificate Manager編
  7. Lambda編

関連記事

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

やりたかったこと

  • SSL証明書発行時のドメイン認証メールをSESにて受信
  • 受信メールをS3バケットに保存
  • GUIを使わずに黒い画面でコマンドを「ッターーン!」してかっこつけたい

やったこと

前提

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

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

作業フロー

1. ドメイン認証用のトークンを発行

command
ansible-playbook -i inventory/production create-aws-ses-token.yml

※戻り値の値を控えます

2. Route53のレコードセットの更新

command
ansible-playbook -i inventory/production update-aws-route53-record-set.yml

3. Route53の承認ステータスの確認

command
ansible-playbook -i inventory/production view-aws-ses-verification-status.yml

VerificationStatusがSuccessになることを確認します。
※多少時間がかかる場合があります

4. メール保存用のS3バケットを作成

command
ansible-playbook -i inventory/production setup-aws-s3-bucket.yml

5. SESルール周りのセットアップの作成

command
ansible-playbook -i inventory/production setup-aws-ses-rule.yml

ディレクトリ構成


├── ansible.cfg
├── create-aws-ses-token.yml
├── templates
│   └── production
│       ├── route53
│       │   └── record_set.j2
│       ├── s3api
│       │   └── s3-policy.j2
│       └── ses
│           └── rule-set.j2
├── inventory
│   └── production
│       └── inventory
├── roles
│   ├── active-aws-ses-rule-set
│   │   └── tasks
│   │       └── main.yml
│   ├── create-aws-s3-bucket
│   │   └── tasks
│   │       └── main.yml
│   ├── create-aws-ses-rule
│   │   └── tasks
│   │       └── main.yml
│   ├── create-aws-ses-rule-set
│   │   └── tasks
│   │       └── main.yml
│   ├── create-aws-ses-token
│   │   └── tasks
│   │       └── main.yml
│   ├── setup-aws-s3-bucket
│   │   └── tasks
│   │       └── main.yml
│   ├── update-aws-route53-record-set
│   │   └── tasks
│   │       └── main.yml
│   └── view-aws-ses-verification-status
│       └── tasks
│           └── main.yml
├── setup-aws-ses-rule.yml
├── setup-aws-s3-bucket.yml
├── update-aws-route53-record-set.yml
├── view-aws-ses-verification-status.yml
└── vars
    └── all.yml

Ansible構成ファイル

inventory

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

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

[all:vars]
ENV=production

vars

vars/all.yml
SERVER_IP: ${IPアドレス}
TEMP:
  DIRECTORY: /temp
DOMAIN:
  MAIN:
    NAME: ${ドメイン名}
  SUB:
    NAME: ${サブドメイン名}
AWS:
  ROUTE53:
    HOSTED_ZONE_ID: ${ホストゾーンID}
  S3:
    BUCKET:
      NAME: ${バケット名}
  SES:
      TOKEN: ${認証トークン}
      REGION: us-west-2
    RULE:
      NAME: ${ルール名}
      SET:
        NAME: ${ルールセット名}

templates

json/production/ses/rule-set.j2
{
  "Name": "{{ AWS.SES.RULE.NAME }}",
  "Enabled": true,
  "TlsPolicy": "Optional",
  "Recipients": [
    "admin@{{ DOMAIN.MAIN.NAME }}",
    "admin@{{ DOMAIN.SUB.NAME }}"
  ],
  "Actions": [
    {
      "S3Action": {
        "BucketName": "{{ AWS.S3.BUCKET.NAME }}"
        }
    }
  ],
  "ScanEnabled": true
}
s3-policy.j2
{
  "Version":"2012-10-17",
  "Statement":[{
      "Sid":"AddPerm",
      "Effect":"Allow",
        "Principal": "*",
      "Action":["s3:PutObject"],
      "Resource":["arn:aws:s3:::{{ AWS.S3.SES.NAME }}/*"]
    }
  ]
}
record_set
{
  "Comment": "DomainRecords",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "EvaluateTargetHealth": false,
          "DNSName": "{{ DOMAIN.MAIN.NAME }}"
        },
        "Type": "A",
        "Name": "{{ DOMAIN.MAIN.NAME }}"
      }
    },
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "{{ DOMAIN.SUB.NAME }}",
        "Type": "A",
        "TTL": 1200,
        "ResourceRecords": [
          {
            "Value": "{{ SERVER_IP }}"
          }
        ]
      }
    },
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "_amazonses.{{ DOMAIN.MAIN.NAME }}.",
        "Type": "TXT",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "\"{{ AWS.SES.TOKEN }}\""
          }
        ]
      }
    },
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "{{ DOMAIN.MAIN.NAME }}.",
        "Type": "MX",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "10 inbound-smtp.{{ AWS.SES.REGION }}.amazonaws.com."
          }
        ]
      }
    }
  ]
}

playbook

create-aws-ses-token.yml
- hosts: cliservers
  roles:
    - create-aws-ses-token
  vars_files:
    - vars/all.yml
setup-aws-ses-rule.yml
- hosts: cliservers
  roles:
    - create-aws-ses-rule-set
    - create-aws-ses-rule
    - active-aws-ses-rule-set
  vars_files:
    - vars/all.yml
setup-aws-s3-bucket.yml
- hosts: cliservers
  roles:
    - create-aws-s3-bucket
    - setup-aws-s3-bucket
  vars_files:
    - vars/all.yml
update-aws-route53-record-set.yml
- hosts: cliservers
  roles:
    - update-aws-route53-record-set
  vars_files:
    - vars/all.yml
view-aws-ses-verification-status.yml
- hosts: cliservers
  roles:
    - view-aws-ses-verification-status
  vars_files:
    - vars/all.yml

tasks

role/active-aws-ses-rule-set/tasks/main.yml
- name: Active Receipt Rule Set
  shell: |
    aws ses set-active-receipt-rule-set \
    --region={{ AWS.SES.REGION }} \
    --rule-set-name {{ AWS.SES.RULE.SET.NAME }}
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/create-aws-s3-bucket/tasks/main.yml
- name: Create Bucket
  shell: "aws s3 mb s3://{{ AWS.S3.BUCKET.NAME }}"
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/create-aws-ses-rule-set/tasks/main.yml
- name: Create Receipt Rule Set
  shell: |
    aws ses create-receipt-rule-set \
    --region={{ AWS.SES.REGION }} \
    --rule-set-name {{ AWS.SES.RULE.SET.NAME }} 
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/create-aws-ses-rule/tasks/main.yml
- name: Create Replaced File
  template: 
    src={{ ENV }}/ses/rule-set.j2
    dest={{ TEMP.DIRECTORY }}/rule-set.json
  tags:
    - always

- name: Create Receipt Rule
  shell: |
    aws ses create-receipt-rule \
    --region={{ AWS.SES.REGION }} \
    --rule-set-name {{ AWS.SES.RULE.SET.NAME }} \
    --rule file://{{ TEMP.DIRECTORY }}/rule-set.json
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/create-aws-ses-token/tasks/main.yml
- name: "Create SES Token"
  shell: |
    aws ses verify-domain-identity  \
    --domain "{{ DOMAIN.MAIN.NAME }}" \
    --region={{ AWS.SES.REGION }}
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/setup-aws-s3-bucket/tasks/main.yml
- name: Create Replaced File
  template: 
    src={{ ENV }}/s3api/s3-policy.j2
    dest={{ TEMP.DIRECTORY }}/s3-policy.json
  tags:
    - always

- name: Create Policy
  shell: |
    aws s3api put-bucket-policy \
    --bucket {{ AWS.S3.BUCKET.NAME }} \
    --policy file://{{ TEMP.DIRECTORY }}/s3-policy.json
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/update-aws-route53-record-set/tasks/main.yml
- name: Create Replaced File
  template: 
    src={{ ENV }}/route53/record_set.j2
    dest={{ TEMP.DIRECTORY }}/record_set.json
  tags:
    - always

- name: Update Record Set
  shell: |
    aws route53 change-resource-record-sets \
    --hosted-zone-id {{ AWS.ROUTE53.HOSTED_ZONE_ID }} \
    --change-batch file://{{ TEMP.DIRECTORY }}/record_set.json
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
role/view-aws-ses-verification-status/tasks/main.yml
- name: View Verification Status
  shell: |
    aws ses get-identity-verification-attributes \
    --identities ${DOMAIN.MAIN.NAME}
  register: result
  changed_when: False

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

終わりに

上記作業が正常に終了すれば、SSL証明書発行時のドメイン認証メールをSESにて受信及びS3バケットへの保存が可能になりました。

ただ、S3バケット上で保存している電子メールは そのままだと解読が出来ない ので、オブジェクトをローカル等にダウンロードした上で内容を表示する必要があります。(Lambdaを使えば転送とかもできるかも?)

ここまでの設定をすればACMにて無料のSSL証明書を発行する準備が出来たので、
CloudFront+S3+ACMによる無料SSLサイトを構築することが可能 です。

AWSサービス同士はとても連携しやすく、同サービス内だからこそのメリットもたくさんあるので他にも良い組み合わせがあったら記事にまとめていこうと思います♪

じゃあの。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2