web app en aws con cloudfront

Automatiza tu despliegue de infraestructura de archivos estáticos en aws con CloudFront, s3 y tu dominio ssl .

El objetivo es automatizar el despliegue de nuestra aplicación ya sea una web app en vue, react, angular etc... con certificado https y con nuestro propio dominio.

Vamos a crear nuestra infraestructura con cloudformation para tener un mejor control de lo que creamos.

  1. Como parámetro vamos a recibir:
  • domainName : Nuestro dominio donde queremos ver nuestra web app
AWSTemplateFormatVersion: "2010-09-09"
Description: Devops blog  


Parameters:
  domainName:
    Type: String
    Default: example.ncleguizamon.co

2. Crear certificado ssl.

.....
Resources:
  myCertificate:
    Type: 'AWS::CertificateManager::Certificate'
    Properties:
      DomainName: !Ref domainName
    
    
....

3. Crear Bucket s3, es donde vamos a poner nuestros archivos estáticos .js .html img ...

...
AppBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: !Ref domainName 
      #AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: index.html
    #DeletionPolicy: Retain
    
 ...
    

4. Creamos una identidad de acceso de origen es un usuario especial de CloudFront que puede asociar con orígenes de Amazon S3

......
  originAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: " OAI"
.....

5. Creamos la política de acceso al s3.

.....

  BucketPolicy: 
    Type: AWS::S3::BucketPolicy
    Properties: 
      Bucket: 
        Ref: "AppBucket"
      PolicyDocument: 
        Statement: 
          - 
            Action: 
              - "s3:GetObject"
            Effect: "Allow"
            Resource: 
              Fn::Join: 
                - ""
                - 
                  - "arn:aws:s3:::"
                  - 
                    Ref: "AppBucket"
                  - "/*"
            Principal:
              AWS:
                Fn::Join: 
                  - ""
                  - 
                    - "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity "
                    - 
                      Ref: "originAccessIdentity"
                    - ""
                

6. Creamos la distribución de CloudFront

  CloudFrontDistribution:
    Type: 'AWS::CloudFront::Distribution'
    Properties:
      DistributionConfig:
        Aliases:
        - !Ref  domainName
        DefaultCacheBehavior:
          AllowedMethods:
          - "GET"
          - "HEAD"
          - "OPTIONS"
          DefaultTTL: 3600
          ForwardedValues:
            QueryString: true
            Cookies:
              Forward: "none"
          TargetOriginId: "S3Origin"
          ViewerProtocolPolicy: "redirect-to-https"
        CustomErrorResponses:
        - ErrorCode: '403'
          ResponsePagePath: "/"
          ResponseCode: '200'
          ErrorCachingMinTTL: '0'
        DefaultRootObject: "index.html"
        Enabled: true
        HttpVersion: http2
        Origins:
          - DomainName: 
              Fn::GetAtt: 
                - AppBucket
                - DomainName
            S3OriginConfig:
              OriginAccessIdentity: !Join ["", ["origin-access-identity/cloudfront/", !Ref originAccessIdentity]]
            Id: S3Origin
        ViewerCertificate:
          AcmCertificateArn: !Ref DomainCertificateArn
          SslSupportMethod: sni-only

7. Configuramos nuestro dns con Route53.

  route53:
    Type: 'AWS::Route53::RecordSetGroup'
    Properties:
      HostedZoneName: ncleguizamon.co.
      RecordSets:
      - Name: !Ref domainName
        Type: A
        AliasTarget:
          DNSName: !GetAtt 'CloudFrontDistribution.DomainName'
          #EvaluateTargetHealth: false
          HostedZoneId: Z2FDTNDATAQYW2 #https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html#cfn-route53-aliastarget-hostedzoneid

8. Por último subimos nuestra web app a s3, en nuestro caso es el nombre del dominio s3://example.ncleguizamon.co

AWS::Route53::RecordSetGroup AliasTarget - AWS CloudFormation
When creating records for a private hosted zone, note the following: