全国1億人のサーバーワークスファンの皆さま、初めまして。2015年10月に入社しました法人営業課ソリューションアーキテクト(試用期間中)の浦底(@urasoko)と申します。試用期間中のくせにブログを書こうと下書きを寝かせていたら、人事にも課長にも先に出されてしまいました。くやしいです。これからどうぞお手柔らかによろしくお願いいたします。
Chefって
さて、唐突ですがみなさん、Chefってご存知ですよね。そうですあのChefです。説明はここでは省きます。
サーバーワークスがSlackを導入しているのは皆さまご存知かと思います。そこに #chef_study ってチャンネルがあったわけですよ。そしたらなんとメンバーがゼロだったわけですよ、ゼロ。
おそるおそるPreviewしてみると2014年9月で更新が止まってるというなんと。
Chefはもうオワコンなのか
そういえばもう12月ですね。12月といえばAdvent Calendarですね。試しにChefでAdvent Calendar検索したら2014年のがトップに出てきたわけですよもう。
Chefはやはりオワコンなのか
閑話休題(書きたかっただけ)
さて、そんなご時世ですが、本日はchef-provisioning-awsをご紹介いたします。
Chef Provisioningって
まず、Chefといえば単独のNode(EC2でいえばインスタンス)に対し、chef-client君がよしなに自動化してくれるというご理解を皆さまお持ちと思います。それ以上の説明はここでは省きます。マサカリも受け付けません。
さらに、今回のchef-provosioning-awsの前にchef-provisioningを説明しないといけないのですが、こちらは上記の単独Nodeに対する自動化の一段上層で動作するフレームワークです。すなわち複数Nodeのクラスタリングの自動化を実現します。それ以上の説明はここでは省きます(以下同文
で、それ以上にchef-provisioningの良いところが2点あります。まずはNodeの上層で実現したい要求を実装できるというところ。例えば、Node間の相互関連や、関連づけるための概念の事前定義、関連を紐付けるための役割の事後処理などなど。
もう一つはその処理要求をChefのフレームワーク内というよりもRubyで実装可能なところです。つまりAWSであればaws-sdk-rubyを自在に活用可能というところです。一つ目の利点に重ねるとVPC作ってSubnet定義してからMulti Availability Zoneにインスタンス起動して、最後にELBにぶら下げるみたいな。
Chef Provisioning AWSって
現にchef-provisioning-awsに標準で用意されているAWS Driver Resourceには以下のようなものがあります。
- aws_auto_scaling_group
- aws_cache_cluster
- aws_cache_replication_group
- aws_cache_subnet_group
- aws_cloudsearch_domain
- aws_dhcp_options
- aws_ebs_volume
- aws_eip_address
- aws_image
- aws_instance
- aws_internet_gateway
- aws_key_pair
- aws_launch_configuration
- aws_load_balancer
- aws_network_acl
- aws_network_interface
- aws_rds_instance
- aws_rds_subnet_group
- aws_route_table
- aws_s3_bucket
- aws_security_group
- aws_server_certificate
- aws_sns_topic
- aws_sqs_queue
- aws_subnet
- aws_vpc
Resource名から分かるとおり、Computing以外のAWSリソースを扱えることがお分かりかと思います。また、chef-provisioningの標準Resourceのうち、load_balancerはELBをAWS Driverにて実装しています。
余談ですが、上記のとおり昨今のフレームワークに多い、実装をPlugin/Driverに委ねることで抽象化と自由度を高めたフレームワークです。AWS Driver Resourceの種類が豊富なのもその恩恵に依るところがあると思います。
試してみる
とりあえず手っ取り早く試してみるところまで。
chef-provisioningはchef-clientのlocal modeで動作しますので、実行するにはchef-clientが必要です。今はChefDKパッケージにchef-provisioningもchef-provisioning-awsも(その他諸々もろ…以下略)入ってますので良ければどうぞ。
今回は↓のようなコードを試してみます。
上から、VPC掘って、Subnet分けて、RDSインスタンス上げて、EC2インスタンス2個あげて、ELBあげてインスタンス2個ぶら下げる感じです。本来ならNACLやSecurity Groupの設定などなど細かくやらんといけないのですが、今回は分かりやすさのために省いてます(もちろん設定は可能です)。
実行してみると↓な感じに流れます。
mbp:chef-provisioning-aws ura$ chef-client -z chef-prov-test.rb [2015-12-28T09:59:27+09:00] WARN: No config file found or specified on command line, using command line options. Starting Chef Client, version 12.5.1 resolving cookbooks for run list: [] Synchronizing Cookbooks: Compiling Cookbooks... Converging 7 resources Recipe: @recipe_files::/Users/ura/swx/chef-provisioning-aws/chef-prov-test.rb * aws_vpc[test-vpc] (vpc-9ed44efb) action create - waited 0/300s for #state state to change to [:available]... - create VPC test-vpc in ap-northeast-1 - update data bag item test-vpc at chefzero://localhost:8889 - update reference.id from "vpc-9ed44efb" to "vpc-20d54f45" - attach vpc vpc-20d54f45 to igw-3d248558 - create internet gateway igw-managed-by-vpc-20d54f45 in region ap-northeast-1 - create data bag item igw-managed-by-vpc-20d54f45 at chefzero://localhost:8889 - add reference = {"id"=>"igw-3d248558"} - add driver_url = "aws::ap-northeast-1" - creating tags {"OwnedByVPC"=>"vpc-20d54f45"} - route 0.0.0.0/0 to internet_gateway (igw-3d248558) * aws_subnet[test-subnet-a] (subnet-f7641c80) action create - create subnet test-subnet-a with CIDR 10.0.0.0/26 in VPC test-vpc (vpc-20d54f45) in ap-northeast-1 - update data bag item test-subnet-a at chefzero://localhost:8889 - update reference.id from "subnet-f7641c80" to "subnet-a5641cd2" - turn on automatic public IPs for subnet subnet-a5641cd2 * aws_subnet[test-subnet-c] (subnet-1167f748) action create - create subnet test-subnet-c with CIDR 10.0.0.64/26 in VPC test-vpc (vpc-20d54f45) in ap-northeast-1 - update data bag item test-subnet-c at chefzero://localhost:8889 - update reference.id from "subnet-1167f748" to "subnet-c267f79b" - turn on automatic public IPs for subnet subnet-c267f79b * aws_rds_subnet_group[test-db-subnet] action create - create RDS subnet group test-db-subnet in ap-northeast-1 * aws_rds_instance[test-rds] action create - create RDS instance test-rds in ap-northeast-1 * machine_batch[default] action allocate - create chef_default on aws::ap-northeast-1 from local key at - creating machine machine2 on aws::ap-northeast-1 - max_count: 1 - min_count: 1 - instance_type: "t2.micro" - image_id: "ami-d3a194bd" - key_name: "chef_default" - subnet_id: "subnet-c267f79b" - creating machine machine1 on aws::ap-northeast-1 - max_count: 1 - min_count: 1 - instance_type: "t2.micro" - image_id: "ami-d3a194bd" - key_name: "chef_default" - subnet_id: "subnet-a5641cd2" - machine machine1 created as i-7f4503da on aws::ap-northeast-1 - [machine1] update node machine1 at chefzero://localhost:8889 - [machine1] update normal.chef_provisioning.reference.allocated_at from "2015-12-25 12:35:25 UTC" to "2015-12-28 00:59:52 UTC" - [machine1] update normal.chef_provisioning.reference.instance_id from "i-5a6025ff" to "i-7f4503da" - machine machine2 created as i-a276d12d on aws::ap-northeast-1 - [machine2] update node machine2 at chefzero://localhost:8889 - [machine2] update normal.chef_provisioning.reference.allocated_at from "2015-12-25 12:35:24 UTC" to "2015-12-28 00:59:52 UTC" - [machine2] update normal.chef_provisioning.reference.instance_id from "i-2ae94ca5" to "i-a276d12d" * load_balancer[test-elb] action create - create load balancer test-elb in ap-northeast-1 - attach subnets #, # - with listeners [{:port=>80, :protocol=>:http, :instance_port=>80, :instance_protocol=>:http}] - add machines machine1, machine2 - update data bag item test-elb at chefzero://localhost:8889 - update reference.allocated_at from "2015-12-25 12:49:43 UTC" to "2015-12-28 00:59:53 UTC" Running handlers: Running handlers complete ...(略)... Chef Client finished, 7/7 resources updated in 26 seconds
さらに今回は、machine_batch Resourceの部分でインスタンスの起動のみ(action :allocate)を指定しましたが、ここでChefのRecipeを実行することも可能です。これでAWSの各種サービスとEC2インスタンスへのミドルウェアプロビジョニングを連携させることが可能です。
と、この他にもいろいろ書きたいことはあるのですが、続きは年明けにでも。
それでは皆さん、良いお年を。