よく大宇宙状態(謎)になっている先輩が、terraform+codedeploy+ansibleを試していたので
本当に使えるかどうか実践してみました。
AWS CodeDeployを使ってAnsible or itamae + Serverspec
http://qiita.com/gamisan9999/items/c4e26bf99189bed82748
全体像
先輩の記事だけ見ていると何しているかよくわかんなかったので、わかりやすくしてみました。
ちなみに、TerraformとCodeDeploy+Ansibleは完全に別物です。
連携はまったくありませんのであしからず。
TerraformでAWS環境を構築、EC2とかCodeDeployとかもろもろ作成。
AnsibleレシピをCodedeployでS3にアップ。
CodeDeployからS3のファイルをデプロイ。
後は、対象のローカルで指定のものが動きます。
今回はAnsibleです。
AWS環境構築
CodeDeploy Agent
CodeDeployを使用するには、サーバー側でCodeDeployAgentを起動しておく必要があります。
http://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/how-to-run-agent.html
しかしAgentを入れるのに、わざわざBaseAMIを用意するのは面倒なので
インスタンス起動時のuser_dataに以下のスクリプトを入れれば
codedeployのAgentが入ります。
http://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/how-to-set-up-new-instance.html
#!/bin/bash yum -y update yum install -y ruby yum install -y aws-cli cd /home/ec2-user aws s3 cp s3://bucket-name/latest/install . --region region-name chmod +x ./install ./install auto
yum updateとか不要であれば外せます。
AWS-CLIで上げるならこんな感じ。
aws ec2 run-instances --image-id amiID --key-name keyName --user-data file://instance-setup.sh --count 1 --instance-type instanceType --iam-instance-profile Name=CodeDeployDemo-EC2-Instance-Profile
AWS環境構築
例に習ってTerraformで環境構築。
AutoScaleとかしてないで、1インスタンス上げるだけ。
TerraFormの使い方は別途グーグル先生と公式ドキュメントを参考にしていただきたく。
別にTerraform使わなくても大丈夫です。
EC2
気にするところは、user_dataとタグ名。
user_dataはCodeDeployAgent用、
タグはDeploy対象の時のフィルターに使います。
resource "aws_instance" "web-1" { instance_type = "${var.web_instance_type}" ami = "${var.ami_id}" subnet_id = "${aws_subnet.public-1c-subnet.id}" security_groups = ["${aws_security_group.common.id}"] associate_public_ip_address = true key_name = "${var.key_name}" iam_instance_profile = "${aws_iam_instance_profile.public-profile.name}" user_data = "${file("./shells/user_data.sh")}" ※ここにuser_data指定 tags = { Name = "web-1" Role = "web" ※codedeployに用にタグ指定 } root_block_device = { volume_type = "gp2" volume_size = "100" } }
S3
CodeDeployで使用するS3バケットを作る。
バージョニングを有効にする。
resource "aws_s3_bucket" "deploy_bucket" { bucket = "hogehoge-deploy-bucket" acl= "private" region = "ap-northeast-1" tags { Name = "hogehoge-deploy-bucket" } versioning { enabled = true } }
Codedeploy
IAM
CodeDeploy自体が使用するIAMRoleを作成。
http://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/how-to-create-service-role.html
resource "aws_iam_role" "codedeploy_role" { name = "codedeploy_role" assume_role_policy = <CodeDeployの定義を作成
対象インスタンスのフィルターはタグ名で行ってます。
先輩の記事には、タグが2つ指定されてますが、CodeDeployのタグはAND条件ではないので、
2つ付けても対象が増えるだけです。resource "aws_codedeploy_app" "web-provisioning" { name = "web-provisioning" } resource "aws_codedeploy_deployment_group" "web-provisioning-group" { app_name = "${aws_codedeploy_app.web-provisioning.name}" deployment_group_name = "web-group" service_role_arn = "${aws_iam_role.codedeploy_role.arn}" ec2_tag_filter { key = "Role" value = "web" type = "KEY_AND_VALUE" } deployment_config_name = "CodeDeployDefault.AllAtOnce" }これでAWS構築は終わり。
Ansible + CodeDeploy
Ansible作成
動作としては、S3に配置しているAnsibleを配布、各サーバ自身でLocalHost宛に実行します。
appspec.ymlの書き方さえわかれば、後はAnsibleの書き方がわかれば大丈夫です。
ディレクトリ階層はこちらを参考にしてます。
https://github.com/awslabs/aws-codedeploy-samples/tree/master/conf-mgmt/ansible/local-only
appspec.yml
version: 0.0 os: linux files: - source: / destination: /etc/ansible/codedeploy hooks: BeforeInstall: - location: before_install.sh timeout: 300 runas: root ApplicationStart: - location: application_start.sh timeout: 300 runas: root ValidateService: - location: verify_service.sh timeout: 300 runas: rootCodeDeployにpush
webというフォルダに、先ほどのファイル構成のものを準備してpushする。
aws deploy push --application-name web-provisioning --s3-location s3://hogehoge-deploy-bucket/web-ansible.zip --source ./web/ --ignore-hidden-files --profile hoehoge --region ap-northeast-1Deploy
後はCLIでpushするもよし、ConsoleからDeployするもよしとなります。
使ってみて
Terraformは便利です。
CodeDeployはAnsibleを作る手間と、一々pushするのが面倒でした。
また、pushした後のDeployも面倒。現状だと、ローカルからAnsibleを普通に実行したほうが便利じゃないか?っと思いましたが、
バージョン管理等はCodeDeployが優れているかなと思いました。Ansibleの資産があっても、修正する手間は多少あるのでその分の価値が見いだせるかというと微妙。
Auto Scaling 等の組み合わせがCodeDeployにはよさそうですので、もう少し触ってから結論を出したいと思います。
元記事はこちら