diff --git a/README.md b/README.md index aa80221..d94e9f2 100644 --- a/README.md +++ b/README.md @@ -4,30 +4,42 @@ Best Stock Management System application. ## Descripción de los módulos +### ACM + ### API Gateway -Construye una API REST que puede recibir requests POST, GET u OPTIONS. En el caso de GET, va directo a la lambda de lectura de la tabla (`lambdaDB`). Por otro lado, en el caso de un POST, se encola en el SQS para luego ir a otra lambda (`lambdaSQSDB`). Finalmente, el OPTIONS se utiliza para poder soportar y habilitar `CORS` y que, por ende, funcionen correctamente los llamados a la API desde el sitio estático. +Construye una API REST que puede recibir requests POST, GET, PUT, DELETE y OPTIONS. En el caso de GET, va directo a la lambda de lectura de la tabla (`lambdaDB`). Por otro lado, en el caso de un POST, se encola en el SQS para luego ir a otra lambda (`lambdaSQSDB`). Finalmente, el OPTIONS se utiliza para poder soportar y habilitar `CORS` y que, por ende, funcionen correctamente los llamados a la API desde el sitio estático. + +Ver [apigw/README.md](terraform/modules/apigw/README.md) ### CloudFront Funciona como CDN y realiza caché de la API y del S3 (que hostea el sitio estático). +### Cognito + ### Dynamo DB -Guarda los datos de los stocks de los usuarios. Tiene una tabla compuesta por `id` (la partition key) y `stock`. +Guarda el stock de los productos de los usuarios. Tiene una tabla compuesta por `user` (partition key), `id` del producto (sort key) y `stock`. ### Lambda -Definimos 2 lambdas. Una se encarga de realizar escrituras al `DynamoDB` (`lambdaSQSDB`) y la otra de realizar lecturas (`lambdaDB`). +Definimos 9 lambdas. + +### Route53 ### S3 Definimos 3 buckets. Uno para logs y dos para el frontend (el sitio estático en sí y uno `www` que se redirecciona al primero). +### SNS + ### SQS Se encarga de encolar POSTs recibidos por la API. Luego, dispara la lambda correspondiente (en este caso `lambdaSQSDB`). +### Step Functions + ### VPC Este módulo es [externo](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest). Se define en este toda la parte de networking que se detalla en el diagrama de la arquitectura (el cual se encuentra al final de este documento). @@ -36,96 +48,10 @@ Este módulo es [externo](https://registry.terraform.io/modules/terraform-aws-mo Protege la aplicación mediante 3 rules. Esto lo hace mediante la creación de un web ACL asociado a la distribución de CloudFront. -## Descripción y referencia de funciones y meta-argumentos - -Se debe notar que los links solo hacen referencia a la primera aparición en cada archivo. - -### Funciones - -Junto a cada función se especifica para qué se usa. - -- **file**: devuelve como string el contenido del archivo `index.html`. Esto es utilizado para luego poder modificarlo (pues actúa como un template ya que tiene la variable `ENDPOINT` parametrizada) y usarlo. - + [organization/datasources.tf](terraform/organization/datasources.tf#L14) - -- **flatten**: retorna una lista de una dimensión con los elementos de una lista de listas pues así lo espera el módulo. - + [organization/vpc.tf](terraform/organization/vpc.tf#L78) - -- **format**: arma el `path` para un filename dado. - + [modules/s3/main.tf](terraform/modules/s3/main.tf#L39) - -- **jsonencode**: arma un string con un objeto JSON. - + [modules/apigw/main.tf](terraform/modules/apigw/main.tf#L89) - -- **length**: calcula el largo de `custom_origin_config` para saber si debe hacer un `for_each` sobre sus elementos, es decir, para saber si se lo definieron en el archivo que usa el módulo en cuestión. - + [modules/cloudfront/main.tf](terraform/modules/cloudfront/main.tf#L20) - -- **lookup**: obtiene el valor de un mapa para una key. - + [modules/cloudfront/main.tf](terraform/modules/cloudfront/main.tf#L16) - -- **replace**: modifica el `path` para hacerlo válido. - + [modules/s3/main.tf](terraform/modules/s3/main.tf#L38) - + [organization/cloudfront.tf](terraform/organization/cloudfront.tf#L13) - -- **sha1**: computa el `SHA1` del string de la configuración del apigw para saber si se necesita forzar el redeploy del módulo. - + [modules/apigw/main.tf](terraform/modules/apigw/main.tf#L103) - -- **trimsuffix**: remueve substring del final de un string. - + [modules/s3/main.tf](terraform/modules/s3/main.tf#L19) - -- **try**: en caso de que no haya objetos, se utiliza un objeto vacío. - + [modules/s3/main.tf](terraform/modules/s3/main.tf#L35) - + [organization/s3.tf](terraform/organization/s3.tf#L10) - - -### Meta-argumentos - -- **count** - + [modules/s3/main.tf](terraform/modules/s3/main.tf#L18) - -- **depends_on** - + [modules/apigw/main.tf](terraform/modules/apigw/main.tf#L78) - + [organization/apigw.tf](terraform/organization/apigw.tf#L8) - + [organization/cloudfront.tf](terraform/organization/cloudfront.tf#L3) - + [organization/lambda.tf](terraform/organization/lambda.tf#L9) - + [organization/sqs.tf](terraform/organization/sqs.tf#L8) - -- **for_each** - + [modules/cloudfront/main.tf](terraform/modules/cloudfront/main.tf#L12) - + [modules/dynamodb/main.tf](terraform/modules/dynamodb/main.tf#L12) - + [modules/lambda/main.tf](terraform/modules/lambda/main.tf#L15) - + [modules/s3/main.tf](terraform/modules/s3/main.tf#L35) - + [organization/lambda.tf](terraform/organization/lambda.tf#L2) - + [organization/s3.tf](terraform/organization/s3.tf#L2) - -- **lifecycle** - + [modules/apigw/main.tf](terraform/modules/apigw/main.tf#L114) - ## Diagrama de arquitectura deployada -Los servicios que deben ser corregidos (asociados a la entrega del TP3) son los numerados. - architecture ## Demo demo - -## Rúbrica - - - - - - - - - - - - - - - - - -
AlumnoLegajoParticipación
Bellver, Ezequiel6126850%
Lo Coco, Santiago6130150%
diff --git a/terraform/modules/cognito/README.md b/terraform/modules/cognito/README.md index aebeac6..dcfc326 100644 --- a/terraform/modules/cognito/README.md +++ b/terraform/modules/cognito/README.md @@ -23,27 +23,30 @@ No modules. | [aws_cognito_user_pool.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool) | resource | | [aws_cognito_user_pool_client.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_client) | resource | | [aws_cognito_user_pool_domain.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_domain) | resource | +| [aws_lambda_permission.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [account\_recovery\_mechanisms](#input\_account\_recovery\_mechanisms) | (Optional) A list of recovery\_mechanisms which are defined by a `name` and its `priority`. Valid values for `name` are veri fied\_email, verified\_phone\_number, and admin\_only. | `any` | `[]` | no | -| [alias\_attributes](#input\_alias\_attributes) | (Optional) Attributes supported as an alias for this user pool. Possible values: 'phone\_number', 'email', or 'preferred\_username'. Conflicts with username\_attributes. | `set(string)` | `null` | no | -| [auto\_verified\_attributes](#input\_auto\_verified\_attributes) | (Optional) The attributes to be auto-verified. Possible values: 'email', 'phone\_number'. | `set(string)` |
[
"email"
]
| no | -| [client\_name](#input\_client\_name) | (Required) The name of the client user pool. | `string` | n/a | yes | -| [domain](#input\_domain) | (Optional) Type a domain prefix to use for the sign-up and sign-in pages that are hosted by Amazon Cognito, e.g. 'https://{YOUR_PREFIX}.auth.eu-west-1.amazoncognito.com'. The prefix must be unique across the selected AWS Region. Domain names can only contain lower-case letters, numbers, and hyphens. | `string` | `null` | no | -| [enable\_username\_case\_sensitivity](#input\_enable\_username\_case\_sensitivity) | (Optional) Specifies whether username case sensitivity will be applied for all users in the user pool through Cognito APIs. | `bool` | `false` | no | -| [name](#input\_name) | (Required) The name of the user pool. | `string` | n/a | yes | -| [password\_minimum\_length](#input\_password\_minimum\_length) | (Optional) The minimum length of the password policy that you have set. | `number` | `20` | no | -| [password\_require\_lowercase](#input\_password\_require\_lowercase) | (Optional) Whether you have required users to use at least one lowercase letter in their password. | `bool` | `true` | no | -| [password\_require\_numbers](#input\_password\_require\_numbers) | (Optional) Whether you have required users to use at least one number in their password. | `bool` | `true` | no | -| [password\_require\_symbols](#input\_password\_require\_symbols) | (Optional) Whether you have required users to use at least one symbol in their password. | `bool` | `true` | no | -| [password\_require\_uppercase](#input\_password\_require\_uppercase) | (Optional) Whether you have required users to use at least one uppercase letter in their password. | `bool` | `true` | no | +| [account\_recovery\_mechanisms](#input\_account\_recovery\_mechanisms) | A list of recovery\_mechanisms which are defined by a `name` and its `priority`. Valid values for `name` are veri fied\_email, verified\_phone\_number, and admin\_only. | `any` | `[]` | no | +| [alias\_attributes](#input\_alias\_attributes) | Attributes supported as an alias for this user pool. Possible values: 'phone\_number', 'email', or 'preferred\_username'. Conflicts with username\_attributes. | `set(string)` | `null` | no | +| [auto\_verified\_attributes](#input\_auto\_verified\_attributes) | The attributes to be auto-verified. Possible values: 'email', 'phone\_number'. | `set(string)` |
[
"email"
]
| no | +| [client\_name](#input\_client\_name) | The name of the client user pool. | `string` | n/a | yes | +| [domain](#input\_domain) | Type a domain prefix to use for the sign-up and sign-in pages that are hosted by Amazon Cognito, e.g. 'https://{YOUR_PREFIX}.auth.eu-west-1.amazoncognito.com'. The prefix must be unique across the selected AWS Region. Domain names can only contain lower-case letters, numbers, and hyphens. | `string` | `null` | no | +| [enable\_username\_case\_sensitivity](#input\_enable\_username\_case\_sensitivity) | Specifies whether username case sensitivity will be applied for all users in the user pool through Cognito APIs. | `bool` | `false` | no | +| [lambda\_function\_name](#input\_lambda\_function\_name) | Lambda name | `string` | n/a | yes | +| [lambda\_pre\_sign\_up](#input\_lambda\_pre\_sign\_up) | The ARN of a pre-registration AWS Lambda trigger. | `string` | n/a | yes | +| [name](#input\_name) | The name of the user pool. | `string` | n/a | yes | +| [password\_minimum\_length](#input\_password\_minimum\_length) | The minimum length of the password policy that you have set. | `number` | `20` | no | +| [password\_require\_lowercase](#input\_password\_require\_lowercase) | Whether you have required users to use at least one lowercase letter in their password. | `bool` | `true` | no | +| [password\_require\_numbers](#input\_password\_require\_numbers) | Whether you have required users to use at least one number in their password. | `bool` | `true` | no | +| [password\_require\_symbols](#input\_password\_require\_symbols) | Whether you have required users to use at least one symbol in their password. | `bool` | `true` | no | +| [password\_require\_uppercase](#input\_password\_require\_uppercase) | Whether you have required users to use at least one uppercase letter in their password. | `bool` | `true` | no | | [redirect\_url](#input\_redirect\_url) | Redirect URL. | `string` | `null` | no | -| [schema\_attributes](#input\_schema\_attributes) | (Optional) A list of schema attributes of a user pool. You can add a maximum of 25 custom attributes. | `any` | `[]` | no | -| [tags](#input\_tags) | (Optional) A mapping of tags to assign to the resource. | `map(string)` | `{}` | no | -| [temporary\_password\_validity\_days](#input\_temporary\_password\_validity\_days) | (Optional) In the password policy you have set, refers to the number of days a temporary password is valid. If the user does not sign-in during this time, their password will need to be reset by an administrator. | `number` | `1` | no | +| [schema\_attributes](#input\_schema\_attributes) | A list of schema attributes of a user pool. You can add a maximum of 25 custom attributes. | `any` | `[]` | no | +| [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no | +| [temporary\_password\_validity\_days](#input\_temporary\_password\_validity\_days) | In the password policy you have set, refers to the number of days a temporary password is valid. If the user does not sign-in during this time, their password will need to be reset by an administrator. | `number` | `1` | no | ## Outputs diff --git a/terraform/organization/acm.tf b/terraform/organization/acm.tf index cc6691d..d04b3ad 100644 --- a/terraform/organization/acm.tf +++ b/terraform/organization/acm.tf @@ -5,11 +5,6 @@ module "acm" { aws = aws.aws } - # depends_on = [ - # module.route53 - # ] - - # zone_id = module.route53.zone_id domain_name = local.domain subject_alternative_names = [ "*.${local.domain}" diff --git a/terraform/organization/cloudfront.tf b/terraform/organization/cloudfront.tf index dfcdac5..8b1a357 100644 --- a/terraform/organization/cloudfront.tf +++ b/terraform/organization/cloudfront.tf @@ -37,7 +37,7 @@ module "cloudfront" { custom_origin_config = { http_port = 80 https_port = 443 - origin_protocol_policy = "match-viewer" + origin_protocol_policy = "http-only" origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"] } } @@ -45,7 +45,7 @@ module "cloudfront" { default_cache_behavior = { target_origin_id = "s3" - viewer_protocol_policy = "allow-all" + viewer_protocol_policy = "redirect-to-https" allowed_methods = ["GET", "HEAD", "OPTIONS"] cached_methods = ["GET", "HEAD"] diff --git a/terraform/organization/lambda.tf b/terraform/organization/lambda.tf index 6054634..63fd3fc 100644 --- a/terraform/organization/lambda.tf +++ b/terraform/organization/lambda.tf @@ -20,6 +20,4 @@ module "lambda" { vpc_security_group_ids = [each.value.security_group_ids] source_code_hash = filebase64sha256(each.value.package) - - # environment_variables = each.value.environment_variables } diff --git a/terraform/resources/lambda/lambdaError.zip b/terraform/resources/lambda/lambdaError.zip index 013b424..af3740b 100644 Binary files a/terraform/resources/lambda/lambdaError.zip and b/terraform/resources/lambda/lambdaError.zip differ diff --git a/terraform/resources/lambda/lambdaError/lambda_handler.py b/terraform/resources/lambda/lambdaError/lambda_handler.py index 5fb0908..6377b19 100644 --- a/terraform/resources/lambda/lambdaError/lambda_handler.py +++ b/terraform/resources/lambda/lambdaError/lambda_handler.py @@ -4,11 +4,14 @@ import boto3 def main(event, context): print(event) + record = event['Records'][0] + body = record["body"] + body = body.replace('\n', '') + body = json.loads(body) + query = body["body-json"] + message = "Error en la actualización de stock." subject = "BSMSapp" client = boto3.client("sns") - # El dueño del tópico podría salir de la BD, habría que guardar la relación item y dueño. - # Ahora está hardcodeado a un dueño solo (no me parece mal de todos modos para la entrega esta) - # Pero podríamos hacer un get del dynamo y obtener el dueño de ahí sino. - topic_arn = "arn:aws:sns:us-east-1:025685231147:slococo" + topic_arn = "arn:aws:sns:us-east-1:025685231147:" + query["username"] client.publish(TopicArn=topic_arn, Message=message, Subject=subject)