こんにちは、インフラエンジニアの菅原です。
皆さんは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の最新の変更に追従できないこともあります。しかし、うまく使うことで運用をかなり楽にできるができます。