SAM como crear un sitio web en S3
Tags: aws, sam, s3
Published: 2021-10-29 17:22:27

SAM o Serverless Aplication Model: es un framework que sirve para crear infraestructura como código de servicios Serverless en AWS. SAM se basa en CloudFormation para crear la infraestructura.

Algunos de los  beneficios para definir nuestra infraestructura como código son:

Reutilización
Rapidez de los despliegues
Versionamiento de la infraestructura
Ahorro de tiempo


Comandos utilizados en SAM

**_Nota:_** Recuerde que es necesario tener configurada la CLI en el equipo para ejecutar los comandos.

Los comandos utilizados para trabajar con de las plantillas de SAM en AWS son los siguientes:

Sirve para validar que una plantilla este bien construida:


```
sam validate --template
```
Sirve crear un archivo .zip con el código y las dependencias de la plantilla. 


```
sam package [OPTIONS] [ARGS]
```

Sirve para desplegar la infraestructura en AWS.

```
sam deploy -- template
```

En la siguiente plantilla vamos a crear un sitio web estático en AWS.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Description: 
  Creación de un sitio Web con SAM

Parameters:
  NombreSitioWeb: 
    Type: String
    Default: "misitio20211028"

Resources: 

  MiPaginaWEB: 
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref NombreSitioWeb
      AccessControl: "PublicRead"
      WebsiteConfiguration:
        IndexDocument: "index.html"
        ErrorDocument: "error.html"

  MiPaginaWebPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref MiPaginaWEB
      PolicyDocument:
        Id: PublicReadPolicy
        Version: 2012-10-17
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: '*'
            Action: 's3:GetObject'
            Resource: !Sub arn:aws:s3:::${MiPaginaWEB}/*

Outputs:
  WebSiteURL:
      Description: "Url del sitio web creado"
      Value: !GetAtt "MiPaginaWEB.WebsiteURL"
```

A tener en cuenta sobre la plantilla

**_Transform_** indica que es una plantilla SAM y no una plantilla de CloudFormation

```
Transform: AWS::Serverless-2016-10-31
```
**_Parameters_** en esta sesión se definen los parámetros que van a ser usados dentro de la plantilla. Para poder usar los parámetros dentro de la plantilla se utiliza _!Ref NombreDelParametro_

```
Parameters:
  NombreSitioWeb: 
    Type: String
    Default: "misitio20211028"
```
**_Resources:_** nos sirve para definir los recursos que van a ser desplegados en AWS. En esta plantilla se van a definir dos recursos: un Bucket de S3 **_AWS::S3::Bucket_**
 y la política Type: **_AWS::S3::BucketPolicy_**  que va a permitir el acceso publico a los objetos de S3.

```
Resources: 

  MiPaginaWEB: 
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref NombreSitioWeb
      AccessControl: "PublicRead"
      WebsiteConfiguration:
        IndexDocument: "index.html"
        ErrorDocument: "error.html"

  MiPaginaWebPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref MiPaginaWEB
      PolicyDocument:
        Id: PublicReadPolicy
        Version: 2012-10-17
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: '*'
            Action: 's3:GetObject'
            Resource: !Sub arn:aws:s3:::${MiPaginaWEB}/*
```
**_Outputs_** nos sirve para obtener resultado de la ejecución de nuestra plantilla. En este caso se va a retornar la URL del sitio que se acaba de crear.

```
Outputs:
  WebSiteURL:
      Description: "Url del sitio web creado"
      Value: !GetAtt "MiPaginaWEB.WebsiteURL"
```

Después de una descripción de los elementos principales de la plantilla el siguiente paso que se debe realizar es el despliegue de la misma.

El primer paso es asegurarnos que la plantilla este bien construida y para esto debemos ejecutar el siguiente comando en la terminal.

```
sam validate --template sam-template-web-site.yaml
```
Si la plantilla esta construida correctamente vamos a obtener un mensaje similar a este en la terminal:

```
/Users/usuario1/Desktop/SAM Templates/sam-template-web-site.yaml is a valid SAM Template
```
Ahora que sabemos que la plantilla esta bien construida debemos desplegarla en AWS y para esto utilizamos el siguiente comando:

```
sam deploy --template sam-template-web-site.yaml --stack-name ejemplositioweb --parameter-overrides NombreSitioWeb=misitioweb20201028
``` 

Del comando anterior debemos tener presente lo siguiente:
* Se debe dar un nombre al stack que va quedar almacena en CloudFormation, para este caso la parte utilizada del comando es: _--stack-name ejemplositioweb_

* Debemos dar valores a los parámetros que se definieron en la plantilla, para este caso al parámetro NombreSitioWeb se le da el valor de: misitioweb20201028, utilizando **_--parameter-overrides NombreSitioWeb=misitioweb20201028_**
Referencias

Después de ejecutar el comando vamos a ver algo similar en la terminal:

![Resultado Terminal](https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/despliegue%20web%20site%20terminal.png)

Y en la consola de AWS en CloudFormation vamos a ver el Stack desplegado:

![Stack desplegado](https://raw.githubusercontent.com/cecamilo00/posts/circleci-project-setup/stack%20cloudformation.png)

Después que tenemos nuestro sitio desplegado, debemos añadir los archivos **_index.html_** y **_error.html_** a nuestro bucket. Lo podemos realizar desde la consola de AWS agregando los archivos que necesitamos al bucket o lo podemos hacer utilizando la terminal de la siguiente manera:

_Nota: Se debe ubicar en la carpeta donde están los archivos. **Sync** va a subir todos los archivos que se encuentren dentro de la carpeta._

 ```
aws s3 sync . s3://misitioweb20201028

```

Con este vamos a poder ver nuestro sitio web desde la url que nos retorno el comando sam deploy o directamente desde la consola de AWS en el bucket creado.

[SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html)
[CloudFormation](https://aws.amazon.com/es/cloudformation/)

Me pueden encontrar en

[Camilo Cabrales](https://www.linkedin.com/in/camilo-cabrales-31a0bb53/)