Skip to content

Instantly share code, notes, and snippets.

@mbabineau
Last active July 3, 2018 13:34

Revisions

  1. mbabineau revised this gist Jun 6, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion docker-registry.template.json
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    {
    "AWSTemplateFormatVersion" : "2010-09-09",

    "Description" : "Launches a Docker Registry",
    "Description" : "Launches a Docker Registry.",

    "Parameters" : {
    "InstanceType" : {
  2. mbabineau renamed this gist Apr 29, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. mbabineau revised this gist Apr 29, 2014. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion docker-registry.template
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    {
    "AWSTemplateFormatVersion" : "2010-09-09",

  4. mbabineau created this gist Apr 29, 2014.
    242 changes: 242 additions & 0 deletions docker-registry.template
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,242 @@

    {
    "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" }
    }
    }
    }