AWS SAM : How to retrieve implicitly created resources information

Viewed 217

I am using AWS SAM to create infrastructure as code. My current setup (only doing tests for learning) involves among other things this bit of code in the YAML SAM template :

API:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Sub ${Env}
      # Authentication on the API will be performed via a Key
      Auth:
        Authorizers:
            CognitoAuthorizer:
              UserPoolArn: !GetAtt CognitoUserPool.Arn
        DefaultAuthorizer : CognitoAuthorizer
        ApiKeyRequired: true 
        # this creates a key, a usage plan and associate them
        UsagePlan:
          CreateUsagePlan: PER_API
          UsagePlanName: !Sub ${Project}-${Env}-UsagePlan

The UsagePlan part, as specified by the documentation creates an ApiKey, a UsagePlan and an ApiUsagePlan (i.e. an association between the key and the usage plan).

Ok. Now, in a later step, I need to make a call to this API and I therefore the Cognito credentials i.e. my Cognito username and password (ok, that I get since I create the account myself, like a normal user would do) and I also need the Api Key. Now how am I supposed to retrieve that? First as a developer but also for future normal users?

I can't retrieve it through Output in the YAML template. I have tried many things and have read a lot. This is just not possible with SAM.

I can use boto3 to get the UsagePlan id, the ApiKey id and finally the UsagePlanKey. But this seems weird to me because it requires me to go through all existing usage plans and Api keys within the account. And since these ressources are created by SAM... There isn't really a logic I can apply to understand which one I should take. For the UsagePlan I can since I decide its name ... but not for the ApiKey.

So how do I efficiently retrieve the created ressourced id (ApiKey, UsagePlan, UsagePlanKey) by SAM in a "normal" or "state of the art" way ?

Thank you for your support

1 Answers

Consider adding a AWS::ApiGateway::ApiKey resource to your template, here is an example

MyApiKey:
  Type: AWS::ApiGateway::ApiKey
  Properties:
    Name: SomeApiKey
    Description: Some CloudFormation API Key V1
    Enabled: 'true'
    StageKeys:
      - RestApiId: !Ref API
        StageName: !Sub ${Env}

Then sam build && sam deploy and you should be able to derive the API Key value in the Outputs

Perhaps something like:

Outputs:
  MyApiKeyValue:
    Description: "the value of Some CloudFormation API Key V1"
    Value: !GetAtt MyApiKey.Value

More info on AWS::ApiGateway::ApiKey here : https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-apikey.html

Related