How to get Elastic Container Repository URI from Cloud Formation?
Asked Answered
C

3

16

I'm trying to create an Elastic Container Service (ECS) setup from Cloud Formation.

However I don't want the ECS repository to have the ugly autogenerated URI:

111111111.dkr.ecr.us-east-1.amazonaws.com/docker-repo.company.com

but instead I want it to have a nice and shiny

docker-repo.company.com

The repository itself does not allow setting the URI or even a CNAME. So I'm trying to setup a S3 bucket to redirect to the repo. However unless I'm missing something, Cloud Formation doesn't support this since using !Ref or !GetAtt there's nothing I can query in the AWS::ECR::Repository object that will give me the repository URI.

Am I missing something? Thanks!

Complaisance answered 24/8, 2017 at 9:34 Comment(3)
Maybe just run a registry? They're pretty simple to setupFinegan
True, but what would be the point if we plan on using ECS anyway? This way AWS manages it for us, we minimize the number of services we have to manage ourselves.Complaisance
Yeah, only if the requirements that fall outside the specific setup of an ECR are worth it to you.Finegan
C
30

This is kind of silly, but in the end it seems you cannot refer to the URI of an ECR because Cloud Formation doesn't support it.

There's no attribute for the URI, even though funnily enough their Ruby SDK does support it and even the third-party, cross-cloud Terraform supports it.

However, you can hack around this because the repository URI is stable, it doesn't contain any random part, so you can compose the URI from things you already have:

HostName: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${dockerrepocompanycom}"

or for the less cool, old-school version:

HostName: !Join [ ".", [ !Ref "AWS::AccountId", "dkr.ecr", !Ref "AWS::Region", !Join [ "/", [ "amazonaws.com", !Ref "dockerrepocompanycom" ] ] ] ]

Full working configuration for creating the S3 bucket:

   s3dockerrepo1redirect:
    Type: AWS::S3::Bucket
    Properties:
        BucketName: "docker-repo.company.com"
        WebsiteConfiguration:
            RedirectAllRequestsTo:
               HostName: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${dockerrepocompanycom}"
Complaisance answered 24/8, 2017 at 10:15 Comment(1)
You know what's even more disappointing? Having to use a globally distributed infrastructure (Cloud Front) for any kind of setup involving custom domain names and HTTPS, on AWS. Unless I missed something :( I say this because the S3 setup didn't work in the end for our requirements and I had to resort to Cloud Front.Complaisance
W
4
HostName: !Join [ ".", [ !Ref "AWS::AccountId", "dkr.ecr", !Ref "AWS::Region", !Join [ "/", [ "amazonaws.com", !Ref "dockerrepocompanycom" ] ] ] ]

A more concise way is as follows:

HostName: !Sub "${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${dockerrepocompanycom}"

(adding as separate answer because I lack reputation points to comment on previous answer)

Widner answered 5/11, 2018 at 18:35 Comment(3)
If it's ok with you I'll edit my answer to include your improved version.Complaisance
Sure, no problem. Thanks!Widner
Thank you, @sgeb!Lanctot
J
0

It is now possible to get the Repository URI using the GetAtt function in CloudFormation. This functionality was added (or at least documented) in 2021 (sometime between 2021-05-06 and 2021-09-24 according to the Internet Archive). See the current docs here.

In YAML:

HostName: !GetAtt MyRepository.RepositoryUri

Assuming the logical name of the ECR Repository is MyRepository.

And in JSON:

"HostName": {
  "Fn::GetAtt": ["MyRepository", "RepositoryUri"]
}

As an aside, if you're using the Repository for Image-type Lambda functions you can define the Lambda function like this:

  MyFunction:
    Type: AWS::Lambda::Function
    Properties:
      PackageType: Image
      Code:
        ImageUri: !Sub "${MyRepository.RepositoryUri}:tag"
Jargonize answered 28/6 at 12:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.