AnsibleでAWS操作シリーズ
- aws-cliインストール編
- EC2インスタンス編
- S3バケット編
- CloudFrontディストリビューション編
- Simple Email Service編
- Certificate Manager編
- Lambda編
関連記事
やりたかったこと
- 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
サービス同士はとても連携しやすく、同サービス内だからこそのメリットもたくさんあるので他にも良い組み合わせがあったら記事にまとめていこうと思います♪
じゃあの。