{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Sample template to bring up an Opscode Chef Server using the Opscode debian files for installation. This configuration creates and starts the Chef Server with the WebUI enabled, initializes knife and uploads specified cookbooks and roles to the chef server. A WaitCondition is used to hold up the stack creation until the application is deployed. **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.", "Mappings": { "AWSRegion2AMI": { "us-east-1": { "id": "ami-83dee0ea" }, "us-west-1": { "id": "ami-c45f6281" }, "us-west-2": { "id": "ami-d0d8b8e0" }, "eu-west-1": { "id": "ami-aa56a1dd" }, "sa-east-1": { "id": "ami-d55bfbc8" }, "ap-southeast-1": { "id": "ami-bc7325ee" }, "ap-southeast-2": { "id": "ami-e577e9df" }, "ap-northeast-1": { "id": "ami-f72e45f6" } } }, "Parameters": { "KeyName": { "Description": "Name of an existing EC2 KeyPair to enable SSH access to the web server", "Type": "String", "MinLength": "1", "MaxLength": "255", "AllowedPattern": "[\\x20-\\x7E]*", "ConstraintDescription": "can contain only ASCII characters." }, "CookbookLocation": { "Type": "String", "Default": "https://github.com/opscode-cookbooks/aws/tarball/master", "Description": "Location of chef cookbooks to upload to server" }, "RoleLocation": { "Type": "String", "Default": "https://s3.amazonaws.com/cloudformation-examples/example_chef_roles.tar.gz", "Description": "Location of client roles to upload to server" }, "InstanceType": { "Description": "WebServer EC2 instance type", "Type": "String", "Default": "m1.small", "AllowedValues": [ "t1.micro", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.xlarge", "m3.2xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge", "cc2.8xlarge", "cg1.4xlarge" ], "ConstraintDescription": "must be a valid EC2 instance type." }, "SSHLocation": { "Description": "The IP address range that can be used to SSH to the EC2 instances", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "0.0.0.0/0", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." } }, "Resources": { "ChefServerUser": { "Type": "AWS::IAM::User", "Properties": { "Path": "/", "Policies": [ { "PolicyName": "root", "PolicyDocument": { "Statement": [ { "Effect": "Allow", "Action": [ "cloudformation:DescribeStackResource", "s3:Put" ], "Resource": "*" } ] } } ] } }, "HostKeys": { "Type": "AWS::IAM::AccessKey", "Properties": { "UserName": { "Ref": "ChefServerUser" } } }, "ChefServer": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { "config": { "packages": { "apt": { "s3cmd": [ ] } }, "sources": { "/home/ubuntu/chef-repo": "https://github.com/opscode/chef-repo/tarball/master", "/home/ubuntu/chef-repo/cookbooks": { "Ref": "CookbookLocation" }, "/home/ubuntu/chef-repo/roles": { "Ref": "RoleLocation" } }, "files": { "/home/ubuntu/setup_environment": { "source": "https://s3.amazonaws.com/cloudformation-examples/setup-chef-server-with-knife", "mode": "000755", "owner": "ubuntu", "group": "ubuntu" }, "/home/ubuntu/.s3cfg": { "content": { "Fn::Join": [ "", [ "[default]\n", "access_key = ", { "Ref": "HostKeys" }, "\n", "secret_key = ", { "Fn::GetAtt": [ "HostKeys", "SecretAccessKey" ] }, "\n", "use_https = True\n" ] ] }, "mode": "000644", "owner": "ubuntu", "group": "ubuntu" }, "/home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb": { "source": "https://s3.amazonaws.com/cloudformation-examples/chef_11.10.0-1.ubuntu.12.04_amd64.deb", "mode": "000664", "owner": "ubuntu", "group": "ubuntu" }, "/home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb": { "source": "https://s3.amazonaws.com/cloudformation-examples/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb", "mode": "000664", "owner": "ubuntu", "group": "ubuntu" } } } } }, "Properties": { "SecurityGroups": [ { "Ref": "ChefServerSecurityGroup" } ], "ImageId": { "Fn::FindInMap": [ "AWSRegion2AMI", { "Ref": "AWS::Region" }, "id" ] }, "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash\n", "function error_exit\n", "{\n", " cfn-signal -e 1 -r \"$1\" '", { "Ref": "ChefServerWaitHandle" }, "'\n", " exit 1\n", "}\n", "apt-get -y install python-setuptools\n", "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n", "cfn-init --region ", { "Ref": "AWS::Region" }, " -s ", { "Ref": "AWS::StackId" }, " -r ChefServer ", "|| error_exit 'Failed to run cfn-init'\n", "# Bootstrap chef\n", "dpkg -i /home/ubuntu/chef_11.10.0-1.ubuntu.12.04_amd64.deb > /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef client tools'\n", "dpkg -i /home/ubuntu/chef-server_11.0.10-1.ubuntu.12.04_amd64.deb >> /tmp/chef_install.log 2>&1 || error_exit 'Failed to install chef server'\n", "sleep 5\n", "sudo /usr/bin/chef-server-ctl reconfigure > /tmp/chef_configure.log 2>&1 || error_exit 'Failed to configure chef server'\n", "sleep 5\n", "sudo chef-server-ctl start\n", "# Setup development environment in ubuntu user\n", "sudo -u ubuntu /home/ubuntu/setup_environment > /tmp/setup_environment.log 2>&1 || error_exit 'Failed to bootstrap chef server'\n", "# copy validation key to S3 bucket\n", "s3cmd -c /home/ubuntu/.s3cfg put /etc/chef-server/validation.pem s3://", { "Ref": "PrivateKeyBucket" }, "/validation.pem > /tmp/put_validation_key.log 2>&1 || error_exit 'Failed to put Chef Server validation key'\n", "# If all went well, signal success\n", "cfn-signal -e $? -r 'Chef Server configuration' '", { "Ref": "ChefServerWaitHandle" }, "'\n" ] ] } }, "KeyName": { "Ref": "KeyName" }, "InstanceType": { "Ref": "InstanceType" } } }, "ChefServerSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Open up SSH access plus Chef Server required ports", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": { "Ref": "SSHLocation" } }, { "IpProtocol": "tcp", "FromPort": "443", "ToPort": "443", "SourceSecurityGroupName": { "Ref": "ChefClientSecurityGroup" } }, { "IpProtocol": "tcp", "FromPort": "443", "ToPort": "443", "CidrIp": "0.0.0.0/0" } ] } }, "ChefClientSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Group with access to Chef Server" } }, "PrivateKeyBucket": { "Type": "AWS::S3::Bucket", "DeletionPolicy": "Delete", "Properties": { "AccessControl": "Private" } }, "BucketPolicy": { "Type": "AWS::S3::BucketPolicy", "Properties": { "PolicyDocument": { "Version": "2008-10-17", "Id": "WritePolicy", "Statement": [ { "Sid": "WriteAccess", "Action": [ "s3:PutObject" ], "Effect": "Allow", "Resource": { "Fn::Join": [ "", [ "arn:aws:s3:::", { "Ref": "PrivateKeyBucket" }, "/*" ] ] }, "Principal": { "AWS": { "Fn::GetAtt": [ "ChefServerUser", "Arn" ] } } } ] }, "Bucket": { "Ref": "PrivateKeyBucket" } } }, "ChefServerWaitHandle": { "Type": "AWS::CloudFormation::WaitConditionHandle" }, "ChefServerWaitCondition": { "Type": "AWS::CloudFormation::WaitCondition", "DependsOn": "ChefServer", "Properties": { "Handle": { "Ref": "ChefServerWaitHandle" }, "Timeout": "1200" } } }, "Outputs": { "ServerURL": { "Description": "URL of newly created Opscode chef server", "Value": { "Fn::Join": [ "", [ "https://", { "Fn::GetAtt": [ "ChefServer", "PublicDnsName" ] }, ":443" ] ] } }, "ChefSecurityGroup": { "Description": "EC2 Security Group with access to Opscode chef server", "Value": { "Ref": "ChefClientSecurityGroup" } }, "ValidationKeyBucket": { "Description": "Location of validation key", "Value": { "Ref": "PrivateKeyBucket" } } } }