

# Creación de un nombre de dominio personalizado para API privadas mediante CloudFormation
<a name="apigateway-private-custom-domains-cfn"></a>

La siguiente plantilla CloudFormation de ejemplo crea una API privada y un nombre de dominio personalizado privado, asigna la API privada al nombre de dominio personalizado y, a continuación, crea una asociación de acceso a nombres de dominio. Debe proporcionar su propio punto de conexión de VPC, nombre de dominio y ARN de certificado.

Las siguientes consideraciones pueden afectar al uso que haga de CloudFormation para crear un nombre de dominio personalizado privado.
+ No puede rechazar una asociación de acceso a nombres de dominio mediante CloudFormation. Para rechazar una asociación de acceso a nombres de dominio, utilice la AWS CLI.
+ Utilice la propiedad `AWS::ApiGateway::DomainNameV2` de CloudFormation para crear un nombre de dominio personalizado privado.
+ Utilice la propiedad `AWS::ApiGateway:BasePathMappingV2` de CloudFormation para crear una asignación de ruta base.

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  EndpointID:
    Type: String
    Default: {{vpce-abcd1234567efg}}
    Description: A VPC endpoint with enableDnsHostnames and enableDnsSupport set to true.
  DomainName:
    Type: String
    Default: {{private.example.com}}
    Description: A domain name that you own.
  CertificateArn:
    Type: String
    Default: {{arn:aws:acm:us-west-2:123456789:certificate/abcd-000-1234-0000-000000abcd}}
    Description: An ACM certificate that covers the domain name.
Resources:
  PrivateApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      EndpointConfiguration:
        Types:
          - PRIVATE
        VpcEndpointIds:
          - !Ref EndpointID
      Name: private-api
      Policy:
        Statement:
          - Action: 'execute-api:Invoke'
            Effect: Allow
            Principal: '*'
            Resource: 'execute-api:/*'
          - Action: 'execute-api:Invoke'
            Condition:
              StringNotEquals:
                'aws:SourceVpce': !Ref EndpointID
            Effect: Deny
            Principal: '*'
            Resource: 'execute-api:/*'
        Version: 2012-10-17		 	 	 
  PrivateApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    Properties:
      RestApiId: !Ref PrivateApi
      Description: Private API deployment
    DependsOn:
      - PrivateApiMethod
  PrivateApiStage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
      RestApiId: !Ref PrivateApi
      DeploymentId: !Ref PrivateApiDeployment
      StageName: prod
  PrivateApiMethod: 
    Type: 'AWS::ApiGateway::Method'
    Properties:
      HttpMethod: ANY
      ResourceId: !GetAtt PrivateApi.RootResourceId
      RestApiId: !Ref PrivateApi
      AuthorizationType: NONE
      Integration:
        Type: MOCK
        RequestTemplates:
          application/json: "{\"statusCode\": 200}"
        IntegrationResponses:
          - StatusCode: '200'
      MethodResponses:
        - StatusCode: '200'
  PrivateDomainName:
    Type: AWS::ApiGateway::DomainNameV2
    Properties:
      DomainName: !Ref DomainName
      CertificateArn: !Ref CertificateArn
      EndpointConfiguration:
        Types:
          - PRIVATE
      SecurityPolicy: TLS_1_2
      Policy:
        Statement:
            - Action: 'execute-api:Invoke'
              Effect: Allow
              Principal: '*'
              Resource: 'execute-api:/*'
            - Action: 'execute-api:Invoke'
              Condition:
                StringNotEquals:
                  'aws:SourceVpce': !Ref EndpointID
              Effect: Deny
              Principal: '*'
              Resource: 'execute-api:/*'
        Version: 2012-10-17		 	 	 
  PrivateBasePathMapping:
    Type: AWS::ApiGateway::BasePathMappingV2
    DependsOn:
      - PrivateApiStage
    Properties:
      BasePath: prod
      DomainNameArn: !GetAtt PrivateDomainName.DomainNameArn
      RestApiId: !Ref PrivateApi
      Stage: prod
  DomainNameAccessAssociation: 
    Type: AWS::ApiGateway::DomainNameAccessAssociation
    Properties:
      DomainNameArn: !GetAtt PrivateDomainName.DomainNameArn
      AccessAssociationSource: !Ref EndpointID
      AccessAssociationSourceType: VPCE
```