Last active
July 3, 2018 13:34
-
-
Save mbabineau/11387941 to your computer and use it in GitHub Desktop.
Docker Registry CloudFormation template (better version here: https://github.com/mbabineau/cloudformation-docker-registry)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"AWSTemplateFormatVersion" : "2010-09-09", | |
"Description" : "Launches a Docker Registry.", | |
"Parameters" : { | |
"InstanceType" : { | |
"Description" : "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." | |
}, | |
"KeyName" : { | |
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", | |
"Type" : "String" | |
}, | |
"DockerAmi" : { | |
"Description" : "Docker-capable AMI to use for the registry servers", | |
"Type" : "String" | |
}, | |
"ClientSecurityGroup" : { | |
"Description" : "Name of the security group from which clients may access the registry", | |
"Type" : "String" | |
}, | |
"DnsPrefix" : { | |
"Description" : "Prefix for the registry's DNS record (<prefix>.<zone>)", | |
"Type": "String", | |
"Default": "docker" | |
}, | |
"DnsZone" : { | |
"Description" : "Route53-hosted zone to use for the registry's DNS record (<prefix>.<zone>) (e.g., 'mycompany.com')", | |
"Type": "String" | |
}, | |
"RegistryImage" : { | |
"Description" : "Name of the Docker Registry image to use (format: 'registry:port/repository:version'", | |
"Type" : "String", | |
"Default" : "samalba/docker-registry" | |
}, | |
"S3Bucket" : { | |
"Description" : "Bucket to use for Docker images (e.g., 'mycompany-docker')", | |
"Type" : "String", | |
}, | |
"ClusterSize": { | |
"Description" : "Number of Docker Registry servers to run", | |
"Type" : "Number", | |
"Default" : 1 | |
}, | |
"AdminLocation" : { | |
"Description" : "IP address range that can be used to manage the instance and the registry", | |
"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" : { | |
"IAMUser" : { | |
"Type" : "AWS::IAM::User", | |
"Properties" : { | |
"Policies" : [{ | |
"PolicyName" : "S3Access", | |
"PolicyDocument" : { | |
"Statement": [{ | |
"Effect" : "Allow", | |
"Action" : "s3:*", | |
"Resource" : { "Fn::Join" : ["", ["arn:aws:s3:::", {"Ref" : "S3Bucket"} , "/*"]]} | |
}] | |
} | |
}, | |
{ | |
"PolicyName" : "IAMAccess", | |
"PolicyDocument" : { | |
"Statement" : [{ | |
"Effect" : "Allow", | |
"NotAction" : "iam:*", | |
"Resource" : "*" | |
}] | |
} | |
}] | |
} | |
}, | |
"HostKeys" : { | |
"Type" : "AWS::IAM::AccessKey", | |
"Properties" : { | |
"UserName" : { "Ref" : "IAMUser" } | |
} | |
}, | |
"ServerGroup" : { | |
"Type" : "AWS::AutoScaling::AutoScalingGroup", | |
"Properties" : { | |
"AvailabilityZones" : { "Fn::GetAZs" : "" }, | |
"LaunchConfigurationName" : { "Ref" : "LaunchConfig" }, | |
"MinSize" : "1", | |
"MaxSize" : "1", | |
"DesiredCapacity" : "1", | |
"LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ], | |
"VPCZoneIdentifier" : { "Ref" : "Subnets" } | |
} | |
}, | |
"LaunchConfig" : { | |
"Type" : "AWS::AutoScaling::LaunchConfiguration", | |
"Metadata" : { | |
"AWS::CloudFormation::Init" : { | |
"config": { | |
"files" : { | |
"/opt/docker-registry/config.yml" : { | |
"content" : { "Fn::Join" : ["\n", [ | |
"prod:", | |
" loglevel: warn", | |
" storage: s3", | |
" s3_access_key: {{access_key}}", | |
" s3_secret_key: {{secret_key}}", | |
" s3_bucket: {{s3_bucket}}", | |
" boto_bucket: {{s3_bucket}}", | |
" storage_path: /srv/docker", | |
" secret_key: {{magic_string}}" | |
]]}, | |
"context" : { | |
"access_key" : { "Ref" : "HostKeys" }, | |
"secret_key" : { "Fn::GetAtt" : ["HostKeys", "SecretAccessKey"]}, | |
"s3_bucket" : { "Ref" : "S3Bucket"}, | |
"magic_string": "fL3YHeP1cmCHH5FWm1PKaO7cdo0VXkabAgiSEestXYZDgAiQcDCsTiWpOaukB1e9" | |
}, | |
"mode" : "000700", | |
"owner" : "root", | |
"group" : "root" | |
} | |
} | |
} | |
} | |
}, | |
"Properties" : { | |
"KeyName" : { "Ref" : "KeyName" }, | |
"ImageId" : { "Ref" : "DockerAmi" }, | |
"SecurityGroups" : [ { "Ref" : "ServerSecurityGroup" } ], | |
"AssociatePublicIpAddress": "true", | |
"InstanceType" : { "Ref" : "InstanceType" }, | |
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ | |
"#!/bin/bash -ex\n", | |
"# Helper function\n", | |
"function error_exit\n", | |
"{\n", | |
" cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n", | |
" exit 1\n", | |
"}\n", | |
"cfn-init -s ", { "Ref" : "AWS::StackName" }, " -r LaunchConfig ", | |
" --access-key ", { "Ref" : "HostKeys" }, | |
" --secret-key ", {"Fn::GetAtt": ["HostKeys", "SecretAccessKey"]}, | |
" --region ", { "Ref" : "AWS::Region" }, " || error_exit 'Failed to run cfn-init'\n", | |
"# Post-cfn work\n", | |
"sudo docker run -d", | |
" -p 5000:5000", | |
" -v /opt/docker-registry:/registry-conf", | |
" -e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml", | |
" -e SETTINGS_FLAVOR=prod", | |
" ", { "Ref": "RegistryImage" }, "|| error_exit 'Failed to launch Docker container'\n", | |
"# All is well so signal success\n", | |
"cfn-signal -e 0 -r \"Stack setup complete\" '", { "Ref" : "WaitHandle" }, "'\n", | |
"#EOF" | |
]]}} | |
} | |
}, | |
"ServerSecurityGroup" : { | |
"Type" : "AWS::EC2::SecurityGroup", | |
"Properties" : { | |
"GroupDescription" : "Enable SSH and Registry access", | |
"VpcId" : { "Ref" : "VpcId" }, | |
"SecurityGroupIngress" : | |
[ { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "AdminLocation"} }, | |
{ "IpProtocol" : "tcp", "FromPort" : "5000", "ToPort" : "5000", "SourceSecurityGroupId" : { "Ref" : "LbSecurityGroup"} }] | |
} | |
}, | |
"LbSecurityGroup" : { | |
"Type" : "AWS::EC2::SecurityGroup", | |
"Properties" : { | |
"GroupDescription" : "Enable Registry access", | |
"VpcId" : { "Ref" : "VpcId" }, | |
"SecurityGroupIngress" : | |
[ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : { "Ref" : "AdminLocation"} }, | |
{ "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "SourceSecurityGroupId" : { "Ref" : "ClientSecurityGroup"} } ] | |
} | |
}, | |
"ElasticLoadBalancer" : { | |
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer", | |
"Properties" : { | |
"SecurityGroups": [{ "Ref": "LbSecurityGroup" }], | |
"Subnets": { "Ref": "Subnets" }, | |
"Listeners" : [ { | |
"LoadBalancerPort" : "80", | |
"InstancePort" : "5000", | |
"Protocol" : "HTTP" | |
} ], | |
"HealthCheck" : { | |
"Target" : "HTTP:5000/", | |
"HealthyThreshold" : "3", | |
"UnhealthyThreshold" : "5", | |
"Interval" : "30", | |
"Timeout" : "5" | |
} | |
} | |
}, | |
"DnsRecord" : { | |
"Type" : "AWS::Route53::RecordSet", | |
"Properties" : { | |
"HostedZoneName" : { "Fn::Join" : [ "", [{"Ref" : "DnsZone"}, "." ]]}, | |
"Comment" : "Docker Registry", | |
"Name" : { "Fn::Join" : [ "", [{"Ref" : "DnsPrefix"}, ".", {"Ref" : "DnsZone"}, "."]]}, | |
"Type" : "CNAME", | |
"TTL" : "900", | |
"ResourceRecords" : [ { "Fn::GetAtt" : [ "ElasticLoadBalancer", "DNSName" ] } ] | |
} | |
}, | |
"WaitHandle" : { | |
"Type" : "AWS::CloudFormation::WaitConditionHandle" | |
} | |
}, | |
"Outputs" : { | |
"DnsAddress" : { | |
"Description" : "Docker Registry", | |
"Value" : { "Ref" : "DnsRecord" } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment