AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: Generate HTML Documentation from CloudFormation template. (qs-1s7dari0n) Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Input configuration Parameters: - AllowedCIDRBlocks - TemplatesBucket - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3KeyPrefix ParameterLabels: AllowedCIDRBlocks: default: Allowed CIDR blocks TemplatesBucket: default: Templates bucket QSS3BucketName: default: Quick Start S3 bucket name QSS3KeyPrefix: default: Quick Start S3 key prefix Parameters: AllowedCIDRBlocks: Type: String Description: Comma-delimited list of CIDR blocks allowed access to the API Gateway endpoint; e.g., '11.12.13.14/24,12.13.14.15/24'. For testing you can use '0.0.0.0/0', this will make your deployed API publicly available. TemplatesBucket: Type: String Description: Pre-existing S3 bucket where privately stored templates can be read from using s3://<bucket>/<key> uri format. If you do not specify this, you can only generate tables for public templates. Default: '' QSS3BucketName: AllowedPattern: '^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$' ConstraintDescription: >- Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Default: aws-cfn-samples Description: >- S3 bucket name for the Quick Start assets. Only change this value if you customize or extend the Quick Start for your own use. This string can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Type: String QSS3KeyPrefix: AllowedPattern: '^[0-9a-zA-Z-/]*[/]$' ConstraintDescription: >- Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/) and must terminate in a forward slash. Default: aws-cloudformation-parameter-table-generator/ Type: String Description: S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). Conditions: TemplatesBucketCondition: !Not - !Equals - !Ref TemplatesBucket - '' Resources: LambdaZipsBucket: Type: AWS::S3::Bucket CopyZips: Type: Custom::CopyZips Properties: ServiceToken: !GetAtt 'CopyZipsFunction.Arn' DestBucket: !Ref 'LambdaZipsBucket' SourceBucket: !Ref 'QSS3BucketName' Prefix: !Ref 'QSS3KeyPrefix' Objects: - 'functions/packages/cfn-table-generator-lambda.zip' - 'templates/cfn-doc-api-swagger-apigw.yaml' CopyZipsRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Path: / Policies: - PolicyName: lambda-copier PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:GetObject Resource: - !Sub 'arn:aws:s3:::${QSS3BucketName}/${QSS3KeyPrefix}*' - Effect: Allow Action: - s3:PutObject - s3:DeleteObject Resource: - !Sub 'arn:aws:s3:::${LambdaZipsBucket}/${QSS3KeyPrefix}*' CopyZipsFunction: Type: AWS::Lambda::Function Properties: Description: Copies objects from a source S3 bucket to a destination Handler: index.handler Runtime: python2.7 Role: !GetAtt 'CopyZipsRole.Arn' Timeout: 240 Code: ZipFile: | import json import logging import threading import boto3 import cfnresponse def copy_objects(source_bucket, dest_bucket, prefix, objects): s3 = boto3.client('s3') for o in objects: key = prefix + o copy_source = { 'Bucket': source_bucket, 'Key': key } print('copy_source: %s' % copy_source) print('dest_bucket = %s'%dest_bucket) print('key = %s' %key) s3.copy_object(CopySource=copy_source, Bucket=dest_bucket, Key=key) def delete_objects(bucket, prefix, objects): s3 = boto3.client('s3') objects = {'Objects': [{'Key': prefix + o} for o in objects]} s3.delete_objects(Bucket=bucket, Delete=objects) def timeout(event, context): logging.error('Execution is about to time out, sending failure response to CloudFormation') cfnresponse.send(event, context, cfnresponse.FAILED, {}, None) def handler(event, context): # make sure we send a failure to CloudFormation if the function # is going to timeout timer = threading.Timer((context.get_remaining_time_in_millis() / 1000.00) - 0.5, timeout, args=[event, context]) timer.start() print('Received event: %s' % json.dumps(event)) status = cfnresponse.SUCCESS try: source_bucket = event['ResourceProperties']['SourceBucket'] dest_bucket = event['ResourceProperties']['DestBucket'] prefix = event['ResourceProperties']['Prefix'] objects = event['ResourceProperties']['Objects'] if event['RequestType'] == 'Delete': delete_objects(dest_bucket, prefix, objects) else: copy_objects(source_bucket, dest_bucket, prefix, objects) except Exception as e: logging.error('Exception: %s' % e, exc_info=True) status = cfnresponse.FAILED finally: timer.cancel() cfnresponse.send(event, context, status, {}, None) CFNDocS3AccessPolicy: Condition: TemplatesBucketCondition Type: AWS::IAM::ManagedPolicy Properties: PolicyDocument: Version: '2012-10-17' Statement: - Action: - 's3:ListBucket' Resource: - !Sub 'arn:aws:s3:::${TemplatesBucket}' Effect: Allow - Action: - 's3:GetObject' Resource: - !Sub 'arn:aws:s3:::${TemplatesBucket}/*' Effect: Allow CFDocGenRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' - !If - TemplatesBucketCondition - !Ref CFNDocS3AccessPolicy - !Ref 'AWS::NoValue' CFNDocApiGatewayCloudWatchLogsRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - apigateway.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs' CFDocGenerator: DependsOn: CopyZips Type: 'AWS::Serverless::Function' Properties: Handler: table-generator-lambda.lambda_handler Runtime: python3.6 CodeUri: Bucket: !Ref LambdaZipsBucket Key: Fn::Sub: '${QSS3KeyPrefix}functions/packages/cfn-table-generator-lambda.zip' Description: Generate HTML Documentation from CloudFormation template MemorySize: 128 Timeout: 180 Role: !GetAtt 'CFDocGenRole.Arn' CFDocGeneratorApi: DependsOn: CFDocGenerator Type: 'AWS::Serverless::Api' Properties: StageName: prod DefinitionBody: 'Fn::Transform': Name: 'AWS::Include' Parameters: Location: s3://aws-cfn-samples/quickstart-cfn-param-table-generator/templates/cfn-doc-api-swagger-apigw.yaml ConfigLambdaPermission: Type: "AWS::Lambda::Permission" DependsOn: - CFDocGenerator Properties: Action: lambda:InvokeFunction FunctionName: !Ref CFDocGenerator Principal: apigateway.amazonaws.com Outputs: CFDocGenerator: Description: CloudFormation table generator function. Value: !Ref CFDocGenerator CFDocGeneratorApi: Description: CloudFormation table generator API name. Value: !Ref CFDocGeneratorApi CFDocGeneratorApiEndpoint: Description: CloudFormation table generator API URL, supply a valid template url at the end. Value: !Sub https://${CFDocGeneratorApi}.execute-api.${AWS::Region}.amazonaws.com/prod/generate-table?url=REPLACE_WITH_TEMPLATE_URL