Search code examples
amazon-web-servicesredisaws-cloudformationamazon-elasticacheaws-policies

Reference arn of a Elasticache cluster in cloudformation


I would like to reference the arn of a "going-to-be-created" Redis ElastiCache cluster in a cloud formation template.
This is the ElasticacheCluster template (tested and working in cloudFormation)

ElasticacheCluster:
Type: AWS::ElastiCache::CacheCluster
Properties:
  AutoMinorVersionUpgrade: 'true'
  Engine: redis
  CacheNodeType: cache.t2.micro
  NumCacheNodes: '1'
  VpcSecurityGroupIds:
  - Fn::GetAtt:
    - ElastiCacheSecurityGroup
    - GroupId
  CacheSubnetGroupName:
    Ref: ElastiCacheSubnetGroup

I cut on the other staff like subnetgroup and security group because it is also not relevant here. I should grant access to the Cluster to another resource with an Access Policies here what I was trying:

AccessPolicies:
    Version: '2012-10-17'
    Statement:
    - Effect: Allow
      Principal:
        AWS: "*"
      Action: es:*
      Resource: !GetAtt ElasticacheCluster.Arn
    - Effect: Allow
      Principal:
        AWS: "*"
      Action: es:*
      Resource: !GetAtt ElasticacheCluster.Arn
      Condition:
        IpAddress:
          aws:SourceIp: 0.0.0.0/0

I saw this:

the !GetAtt ElasticacheCluster.Arn for the resource entry

here but seems not to be working in this case since !GetAtt is returning a fixed set of attributes and ARN is not one of them (as suggested by @Anton in the comments.

I also saw this other question that could solve the issue but I would prefer a not-harcoded-solution being not dependent on things like region and account id.
The solution to the problem seems to be simple but I am struggling to find a clean answer.


Solution

  • I took inspiration from both the @multiscup answer and the one referenced in the question.
    This approach is far from clean and I am waiting for a better answer but at least it is working. The main idea is to construct the string needed for the arn:

    arn:aws:elasticache:region:account-id:cluster:resource-name
    

    To do that I used a join trying to dynamically get the element thanks to the built-in CloudFormation functions:

    Resource: !Join 
            - ':'
            - - 'arn:aws:elasticache' 
              - !Ref 'AWS::Region'
              - '<your-account-id>'
              - 'cluster'
              - !FindInMap [Elasticache, Redis, cluster-name]
    

    I used a Map to define the Redis-cluster because I was using the same value also in other points in the CloudFormation template. Maybe you might find helpful to have the map as well

    Mappings: 
      Elasticache: 
        Redis:
          cluster-name: redis-demo