【问题标题】:Output apikey value in cloud formationcloudformation中输出api键值
【发布时间】:2020-02-21 05:42:52
【问题描述】:

我有一个输出变量的 cloudformation 模板。输出变量之一是

 ApiGKeyId:
    Description: "Api Key Id"
    Value: !Ref ApplicationApiGatewayApiKey

这将返回 API 网关密钥的 ID,而不是实际值。有没有办法获得价值?

【问题讨论】:

    标签: amazon-web-services amazon-cloudformation aws-api-gateway


    【解决方案1】:

    如果有人希望在 Python 中使用自定义资源执行此操作:

    Resources:
      ApiKey:
        Type: AWS::ApiGateway::ApiKey
        Properties:
          Enabled: true
      #######################################################
      ##### Start of Custom functions #####
      #######################################################
      ValueFuncExecutionRole:
        Type: AWS::IAM::Role
        Properties:
          Path: "/"
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
          AssumeRolePolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sts:AssumeRole
                Principal:
                  Service:
                    - lambda.amazonaws.com
          Policies:
            - PolicyName: root
              PolicyDocument:
                Version: "2012-10-17"
                Statement:
                  - Effect: Allow
                    Action: apigateway:GET
                    Resource: !Sub arn:aws:apigateway:${AWS::Region}::/apikeys/${ApiKey}
    
      ValueFunc:
        Type: AWS::Lambda::Function
        Properties:
          Code:
            ZipFile: |
              import boto3
              import cfnresponse
    
              def lambda_handler(event, context):
                response_code = 200
                api_gateway_client = boto3.client('apigateway')
                api_key_id = event['ResourceProperties']['ApiKeyID']
                response = api_gateway_client.get_api_key(
                  apiKey=api_key_id,
                  includeValue=True
                )
                responseValue = response['value']
                responseData = {}
                responseData['Data'] = responseValue
                cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID", noEcho=True)
          Handler: index.lambda_handler
          Runtime: python3.9
          Timeout: 30
          Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/${ValueFuncExecutionRole}"
      GetApiKeyValue:
        Type: Custom::LambdaCallout
        Properties:
          ServiceToken: !GetAtt ValueFunc.Arn
          ApiKeyID: !Ref ApiKey
    
    Outputs:
      APIKeyValue:
        Description: "The actual API Key Value"
        Value: !GetAtt GetApiKeyValue.Data
    

    【讨论】:

      【解决方案2】:

      我必须编写一个部署后脚本,该脚本将读取 API 密钥值并插入到 dynamodb 数据库表中。我使用了 bash 脚本和 aws 控制台的组合。

      # Get the api KeyName from cloudformation output
      awsApiGatewayKeyId=$(get_cf_output ApiGKeyName)
      
      # With the name you call get-api-key and pass the KeyName
      # When used with include-values it return the API key in the property value
      awsApiGatewayKey=$(aws apigateway get-api-keys --name-query $awsApiGatewayKeyId --include-values --query 'items[0].value' --output text )
      
      # Insert the values into Dynamodb for API Authorizer. 
      $(aws dynamodb put-item --table-name $tokenAuthTable --item '{"ApiKey": { "S": "'"$awsApiGatewayKey"'" }, "HmacSigningKey":  { "S": "'"$csapiSecretKey"'"},"Name":  { "S": "'"$stackName"'"}}' )
      

      通过这样做,我不必手动将记录放入 dynamodb 中。

      请参考下面的 URL 获取 api 密钥。 https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-api-key.html

      【讨论】:

      • 注意aws apigateway get-api-keys --name-query需要取API Key的名字,而不是ID。
      【解决方案3】:

      根据下面的帖子不支持属性“Value”~
      https://github.com/awslabs/serverless-application-model/issues/206

      第 3 方维护的可用属性在这里一目了然: https://theburningmonk.com/cloudformation-ref-and-getatt-cheatsheet/

      经过一番研究,我觉得没有其他方法可以检索 ApiKey 的值,只能使用自定义资源调用 lambda 函数。这是我的示例代码。

      #######################################################
      ##### Start of Custom functions #####
      #######################################################
      ValueFunc:
        Type: AWS::Lambda::Function
        Properties:
          Code:
            ZipFile: >
              var response = require('cfn-response');
              var AWS = require('aws-sdk');
      
              exports.handler = function(event, context) {
                var apiKeyID = event.ResourceProperties.ApiKeyID;
                var apigateway = new AWS.APIGateway();
                var params = {
                  apiKey: apiKeyID,
                  includeValue: true
                };
      
                apigateway.getApiKey(params, function(err, ApiKeyData) {
                  if (err) {
                    console.log(err, err.stack); // an error occurred
                    var responseData = { "mykey" : "error reading ApiKey" };
                    response.send(event, context, response.SUCCESS, responseData);
                  } else {
                    console.log(ApiKeyData.value);      // successful response
                    var responseData = { "mykey" : ApiKeyData.value };
                    response.send(event, context, response.SUCCESS, responseData);
                  }
                });
              };
          Handler: index.handler
          Runtime: nodejs8.10
          Timeout: 30
          Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/${LambdaExecutionRole}"
      GetApiKeyValue:
        Type: Custom::LambdaCallout
        Properties:
          ServiceToken: !GetAtt ValueFunc.Arn
          ApiKeyID: !Ref ApiKey
      

      【讨论】:

      • 我认为以上应该被接受为正确答案~
        这是AWS的回复:话虽如此,如果您仍然想检索API密钥的实际值,正如正确指出的那样通过您,我们可以尝试将 Lambda 支持的自定义资源与 AWS CloudFormation 结合使用。 AWS CloudFormation 调用 Lambda API 来调用函数并将所有请求数据(例如请求类型和资源属性)传递给函数。
      猜你喜欢
      • 2019-08-01
      • 1970-01-01
      • 2021-09-27
      • 2022-12-04
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      相关资源
      最近更新 更多