5
votes

I have a cloudformation template to build my api using the API Gateway.

I don't know how to:

  1. Enable cloudwatch logs for the stage in the cloudformation template

  2. Assign the stage to a Custom Domain Name in the cloudformation template.

Is either of these possible in a json cloudformation template?

2
I'm not sure if I understand you Q, first, are you able to see logs in cloudwatch? using serverless framework you could see the dummy template that they create for API Gateway apps, here an exampleuser2976753

2 Answers

3
votes
  • Cloudwatch logs:

Yes you can enable cloudwatch logs in cloudformation:

  1. Configure CloudTrail log file delivery to CloudWatch Logs.
  2. Create a AWS CloudFormation stack by using the template.

the cloudwatch entry should be something simalar to this:

"SecurityGroupChangesAlarm": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
          "AlarmName" : "CloudTrailSecurityGroupChanges",
          "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Security Group.",
          "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
          "MetricName" : "SecurityGroupEventCount",
          "Namespace" : "CloudTrailMetrics",
          "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
          "EvaluationPeriods" : "1",
          "Period" : "300",
          "Statistic" : "Sum",
          "Threshold" : "1"
      }
},

Check the aws official doc everything is detailed there.

  • Custom Domain Name:

the custom domain name is not defined in the cloudformation template. It should be created separately as specified in aws doc:

  1. Sign in to the API Gateway console at https://console.aws.amazon.com/apigateway.
  2. Choose Custom Domain Names from the main navigation pane.
  3. Choose Create in the secondary navigation pane.
  4. In Create Custom Domain Name
  5. setup DNS using Amazon Route 53
3
votes

Update Jul 5 2017: The AWS::ApiGateway::DomainName resource is now available, so a Custom Resource is no longer needed for this part.


Original post Dec 24 2016:

  1. Enable cloudwatch logs for the stage in the cloudformation template

To enable CloudWatch logs for an ApiGateway Stage using CloudFormation for every method call to your API, you need to set the DataTraceEnabled property to true for all methods in your AWS::ApiGateway::Stage resource.

As noted in the Set Up a Stage section of the documentation, you will also need to associate your API Gateway account with the proper IAM permissions to push data to CloudWatch Logs. For this purpose, you will also need to create an AWS::ApiGateway::Account resource that references an IAM role containing the AmazonAPIGatewayPushToCloudWatchLogs managed policy, as described in the documentation example:

CloudWatchRole: 
 Type: "AWS::IAM::Role"
 Properties: 
  AssumeRolePolicyDocument: 
   Version: "2012-10-17"
   Statement: 
    - Effect: Allow
      Principal: 
       Service: 
        - "apigateway.amazonaws.com"
      Action: "sts:AssumeRole"
  Path: "/"
  ManagedPolicyArns: 
   - "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"
Account: 
 Type: "AWS::ApiGateway::Account"
 Properties: 
  CloudWatchRoleArn: 
   "Fn::GetAtt": 
    - CloudWatchRole
    - Arn
  1. Assign the stage to a Custom Domain Name in the cloudformation template

Unfortunately, CloudFormation does not provide an official resource corresponding to the DomainName APIGateway REST API. Fortunately, Carl Nordenfelt's unofficial API Gateway for CloudFormation project does provide Custom::ApiDomainName. Here's the example provided in the documentation:

TestApiDomainName:
    Type: Custom::ApiDomainName
    Properties:
        ServiceToken: {Lambda_Function_ARN}
        domainName: example.com
        certificateName: testCertificate
        certificateBody": "-----BEGIN CERTIFICATE-----line1 line2 ... -----END CERTIFICATE-----"
        certificateChain: "-----BEGIN CERTIFICATE-----line1 line2 ... -----END CERTIFICATE-----"
        certificatePrivateKey: "-----BEGIN RSA PRIVATE KEY-----line1 line2 ... -----END RSA PRIVATE KEY-----"

Also note that once the domain name has been created, you should create a Route53 alias record that points to !GetAtt TestApiDomainName.distributionDomainName and the static CloudFront hosted zone ID (Z2FDTNDATAQYW2), for example:

myDNSRecord:
  Type: AWS::Route53::RecordSet
  Properties: 
    HostedZoneName:
      !Ref HostedZone
    Name:
      !Ref DomainName
    Type: A
    AliasTarget:
      DNSName: !GetAtt TestApiDomainName.distributionDomainName
      HostedZoneId: Z2FDTNDATAQYW2