こんにちは、インフラエンジニアの菅原です。
皆さんはAWSをどのように管理されてますか?
Ansibleでしょうか?ChefやTerraform、CloudFormationでしょうか?
弊社ではAnsibleのAWSモジュールを使って、構成をコード化し、管理しております。
そのため最近関わったプロジェクトでも一人で手早く対応することができました。
今回は便利に使い回せるAWSモジュールを厳選して紹介したいと思います。
AnsibleでAWSを管理する理由
弊社では以下の理由でAnsibleをメインに構成管理を行っています。
- 構成変更の影響範囲をできるだけ小さくしたい(破壊的変更を避けたい)
- エージェントレスで導入コストが少なく、手元で設定を完結したい
- 使うツールは最小限にしたい(新規メンバー参画時の学習コストを減らしたい)
- 前任者の好み
Infrastructure as Codeを挫折してしまう理由が「ちょっと変更したいけどコード化に時間がかかる」や「ここだけ変更したいけど影響範囲が大きい」という要望に簡単に答えられないときだと個人的に思ってます。「手でやった方が早い」という気持ちになってしまうと再現性のない環境が次々とできてしまいかねません。
その点Ansibleであれば、変更箇所を変えて実行するだけですし、変更したい箇所以外はskipされるため影響範囲も最小限に抑えられます。
この記事の前提
この記事の前提は以下となります。
- Ansible2.7系で利用することを前提に記載してます。
- モジュールは順不同になります。
- 以下の図のような構成を目的としたAWSモジュールの紹介になります。

便利AWSモジュール
iam_role
- name: Create IAM roles
iam_role:
state: present
name: "sample-iamrole"
assume_role_policy_document: "{{ lookup('file', 'sample-role.json') }}"
iam_roleはIAMロールを作成、変更することができます。
初回実行時にAWS環境にJSONファイルで用意した内容でIAMロールを作成してくれます。
JSONファイルは以下のようにfilesディレクトリ配下に配置します。
├── files
│ ├── sample-policy.json
│ └── sample-role.json
└── tasks
└── main.yml
IAMロールの設定内容を変更したい場合はJSONファイルを書き換えて実行すれば上書き変更できます。
一つ作ってしまえば使い回しが効くのですごく便利です。
iam_policy
- name: Set policy
iam_policy:
iam_type: role
iam_name: "sample-iamrole"
policy_name: "sample-policy"
policy_json: "{{ lookup('file', 'sample-policy.json') }}"
state: present
iam_policyはIAMのポリシーを作成、変更することができます。
弊社ではtrusted entitiesをiam_roleで設定し、policyをiam_policyで付与しています。
route53
- name: Set Route53
route53:
command: create
zone: "sample.com"
record: "new.sample.com"
type: "A"
ttl: "7200"
value: "dualstack.sample-1111111111.ap-northeast-1.elb.amazonaws.com."
overwrite: "{{ DNS_OVERWRITE | default(false) }}"
alias: "True"
alias_hosted_zone_id: "ZXXXXXXXXXXXXX"
route53はRoute53にDNS設定を追加、変更することができます。
上記はロードバランサー(ELB)に設定する例です。ホスト名の変更を簡単に行うことができるため重宝してます。
既存のレコードを変更する場合はoverwriteをtrueにします。その際は変数を実行時に渡してあげるとroles配下のファイルを書き直さなくても良くなります。
ansible-playbook main.yml -e DNS_OVERWRITE=true
ec2_vpc_net
ec2_vpc_net, ec2_vpc_igw, ec2_vpc_subnetは基本的に新規プロジェクトや環境追加するときにしか実行しませんが、手間が省けたり、環境設定をコードで管理することができるため利用しています。
- name: Create vpc
ec2_vpc_net:
state: present
name: "sample-vpc"
cidr_block: "10.10.0.0/16"
dns_hostnames: yes
dns_support: yes
register: vpc_net
ec2_vpc_netはCIDRブロックを指定してVPCを作成、変更することができます。
変更する対象はcidr_blockとnameで一意に決まります。
ec2_vpc_igw
- name: Create igw
ec2_vpc_igw:
state: present
vpc_id: "{{ vpc_net.vpc.id }}"
ec2_vpc_igwはInternet Gatewayを設定できるモジュールです。
vpc_idにec2_vpc_netで作成したidを渡すことで設定することができます。
例のようにregisterでvpc_idを渡してあげるとスムーズです。
ec2_vpc_subnet
- name: Create subnets
ec2_vpc_subnet:
state: present
vpc_id: "{{ vpc_net.vpc.id }}"
cidr: "{{ item.cidr }}"
az: "{{ item.az }}"
tags: { "Name": "{{ item.name }}" }
with_items:
- { cidr: "10.10.0.0/20", az: "ap-northeast-1a", name: "sample-vpc-subnet1" }
ec2_vpc_subnetはサブネットを設定するモジュールです。
例ではCIDRブロック、Availability Zone、nameタグをwith_itemsに変数として入れて実行しています。
サブネットを複数設定する場合はwith_items構文でループ実行します。
ec2_group
- name: Create security group
ec2_group:
name: "sample-sg"
description: "sample security group"
vpc_id: "{{ vpc_id }}"
rules:
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: "10.10.0.0/20"
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: "0.0.0.0/20"
ec2_groupはセキュリティグループを作成し、対象のVPCに設定することができます。
2回目以降の実行ではセキュリティグループの変更(上書き)を行うことができます。
ただし、AWSのマネジメントコンソールから直接入れた設定があるとロールバックさせてしまうので、実行する前は--checkを付けて変更箇所を確認した方が良いです。
elb_target_group
- name: Create Target Group
elb_target_group:
state: present
name: "sample-alb-target-group"
protocol: http
port: 80
vpc_id: "{{ vpc_id }}"
health_check_protocol: http
health_check_path: /health_check
health_check_interval: 10
health_check_timeout: 5
healthy_threshold_count: 2
unhealthy_threshold_count: 2
deregistration_delay_timeout: 0
successful_response_codes: 200
elb_target_groupはロードバランサーのターゲットグループを作成、変更できます。
例ではリクエストをhttpで80番ポートに受け渡すように設定しています。
ヘルスチェックは要件に合わせて設定値を変えてください。
ターゲットグループにAWSのマネジメントコンソールから追加したインスタンスがあると実行時にターゲットから外れるので注意してください。
elb_application_lb
- name: Create ALB
elb_application_lb:
state: present
name: "sample-alb"
scheme: internet-facing
subnets: "sample-vpc-subnet1"
security_groups:
- "sample-sg"
listeners:
- Protocol: HTTP
Port: 80
DefaultActions:
- Type: forward
TargetGroupName: "sample-alb-target-group"
- Protocol: HTTPS
Port: 443
DefaultActions:
- Type: forward
TargetGroupName: "sample-alb-target-group"
Certificates:
- CertificateArn: "arn:aws:acm:ap-northeast-1:123456789:certificate/aaaa-bbbb-cccc-dddd-eeee"
SslPolicy: ELBSecurityPolicy-2016-08
elb_application_lbはアプリケーションロードバランサーを作成、変更できます。
今まで作成してきたサブネットやセキュリティグループを指定して作成します。
例ではロードバランサーに証明書を設定しています。Certificatesにarnを記述すれば証明書を設定する事ができます。
ALBとして利用するのであればlistenersタグの中にRulesタグを設ければパスで振り分けることができます。(詳しくは公式ドキュメントを確認してください。)
ec2_lc
- name: Create launch configuration
ec2_lc:
state: present
name: "sample-lc"
image_id: "ami-123456789"
key_name: galaxy
security_groups: "sample-sg"
instance_profile_name: "sample-iamrole"
instance_type: "t3.small"
assign_public_ip: yes
volumes:
- device_name: /dev/sda1
volume_size: 32
volume_type: gp2
delete_on_termination: true
register: lc
ec2_lcはAuto Scalingの起動設定を作成、変更をすることができます。
AMIを用意してあればimage_idで指定することで任意のイメージを利用することができます。
弊社ではAMIをAnsibleとPackerで作成しています。
また、EC2のインスタンスサイズやボリームはここで管理する形にしています。
ec2_asg
- name: Set Auto-scaling group
ec2_asg:
state: present
name: "sample-asg"
launch_config_name: "{{ lc.name }}"
health_check_period: 500
health_check_type: EC2
replace_all_instances: yes
min_size: "1"
max_size: "3"
desired_capacity: "2"
vpc_zone_identifier: "sample-vpc-subnet1"
tags:
- Name: "sample-web"
- role: "web"
- env: "cage"
ec2_asgはAuto Scaling グループの作成、変更をすることができます。
ec2_lcでregister: lcを指定しておけばlc.nameを受け渡せます。
弊社ではEC2の起動/停止はec2_asgを使って管理しています。
最後に
今回は弊社でもよく使っているAnsibleのAWSモジュールを紹介しました。
AWSモジュールを利用することでインフラの自動化を進めていますが、Ansibleでは対応していない設定項目やAWSの最新の変更に追従できないこともあります。しかし、うまく使うことで運用をかなり楽にできるができます。