diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index df04027..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,2 +0,0 @@ -#REVIEWERS -* @8infinitecloud \ No newline at end of file diff --git a/.github/workflows/action-post-approve.yaml b/.github/workflows/action-tf-deploy.yaml similarity index 100% rename from .github/workflows/action-post-approve.yaml rename to .github/workflows/action-tf-deploy.yaml diff --git a/.github/workflows/delete-infra.yaml b/.github/workflows/action-tf-destroy.yaml similarity index 100% rename from .github/workflows/delete-infra.yaml rename to .github/workflows/action-tf-destroy.yaml diff --git a/.github/workflows/action-pre-approve.yaml b/.github/workflows/action-tf-plan.yaml similarity index 100% rename from .github/workflows/action-pre-approve.yaml rename to .github/workflows/action-tf-plan.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7ff13a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_STORE \ No newline at end of file diff --git a/README.md b/README.md index 50bc7fa..cd845a2 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,35 @@ -# Despliegue de Infraestructura AWS +# _Jugo de naranja con CodePipeline y Elastic Beanstalk_ -Este repositorio contiene código Terraform para desplegar una infraestructura en AWS que incluye una VPC, subredes públicas y privadas, un NAT Gateway, Elastic Beanstalk para despliegue de aplicaciones, y un pipeline de CodePipeline para automatizar el despliegue de la aplicación en Elastic Beanstalk. +## _Descripción_ -## Estructura del Repositorio +El objetivo de este proyecto es implementar un flujo CI/CD (Integración Continua / Entrega Continua) utilizando GitHub Actions, Terraform y AWS para desplegar la aplicación Juice Shop de OWASP. Juice Shop es una aplicación web de referencia de código abierto para probar y mejorar las habilidades de hacking y seguridad en aplicaciones web. -- `backend.tf`: Define la configuración del backend de Terraform, como el almacenamiento remoto de estado. -- `hs-juice-shop.tf`: Contiene el código Terraform para definir la infraestructura de red, Elastic Beanstalk y el pipeline de CodePipeline. -- `provider.tf`: Define el proveedor de Terraform, en este caso, AWS. -- `README.md`: Este archivo. +## _Objetivos_ -## Configuración de Credenciales +- Configurar un flujo de trabajo de CI/CD utilizando GitHub Actions para automatizar la construcción, pruebas y despliegue de la aplicación Juice Shop. +- Utilizar Terraform para definir la infraestructura necesaria en AWS para desplegar la aplicación. +- Desplegar automáticamente la aplicación en AWS después de que se realicen cambios en el repositorio de infraestructura o aplicación. + +## _Pasos del Proyecto_ + +1. **Pre-requisito de configuraciones de GitHub**: Realizar un fork o clon de este repositorio y configurar un repositorio en GitHub para el proyecto Juice Shop. + +2. **Pre-requesito y estructura del terraform en el Repositorio**: Realizar las configuraciones necesarias de acuerdo al ambiente personal en AWS que tenga para el despliegue de los recursos con terraform. + +3. **Estructura del GitHub Actions en el Repositorio**: Entender el flujo de trabajo de GitHub Actions para automatizar la construcción, pruebas y despliegue de la infraestructura. + +## _Resultados Esperados_ + +Con este proyecto, se espera comprender y practicar el proceso completo de un pipeline CI/CD, desde el código hasta el despliegue de una aplicación, utilizando herramientas modernas como GitHub Actions, Terraform y AWS. + +## _Indicaciones:_ + +## Pre-requisito de configuraciones de GitHub + +### Credenciales AWS +Las credenciales de AWS (AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY) se almacenan como secretos en la configuración del repositorio de GitHub. Estos secretos se utilizan en los flujos de trabajo de GitHub Actions para autenticar y autorizar las operaciones de Terraform en AWS. Al utilizar secretos, se mantiene la seguridad de las credenciales y se evita exponerlas en texto plano en los archivos de configuración. + +#### Configuración de Credenciales Las credenciales de AWS se manejan como secretos de entorno en GitHub Actions para mantenerlas seguras. Sigue estos pasos para configurar las credenciales como secretos de entorno: @@ -22,23 +42,67 @@ Las credenciales de AWS se manejan como secretos de entorno en GitHub Actions pa 7. Repite los pasos 3-6 para crear otro secreto llamado `AWS_SECRET_ACCESS_KEY` y añadir tu clave de acceso secreta de AWS como valor. 8. Estos secretos se utilizarán automáticamente en GitHub Actions para autenticar con AWS al ejecutar Terraform. -## Despliegue +### Protección de la Rama `main` +La protección de la rama `main` está configurada para requerir un pull request antes de fusionar cualquier cambio en esta rama. Esto ayuda a garantizar que los cambios en la infraestructura pasen por una revisión y aprobación adecuadas antes de ser desplegados, lo que reduce el riesgo de errores o cambios no deseados. + +#### Configuración para proteccion de la rama `main` + +1. **Accede al Repositorio:** Ve al repositorio en GitHub que deseas proteger. + +2. **Selecciona la Configuración del Repositorio:** En la parte superior del repositorio, haz clic en la pestaña "Settings" (Configuración). + +3. **Selecciona Branches:** En el menú de la izquierda, haz clic en "Branches" (Ramas). + +4. **Elige la Rama a Proteger:** En la sección "Branch protection rules" (Reglas de protección de ramas), selecciona la rama `main` o la rama principal de tu repositorio. + +5. **Habilita la Protección:** Marca la opción "Protect this branch" (Proteger esta rama). + +6. **Configura las Reglas de Protección:** Aquí puedes configurar varias reglas de protección. Algunas de las más comunes son: + - **Require pull request reviews before merging:** (Requerir revisiones de pull request antes de la fusión) Esto obligará a que todos los cambios sean revisados antes de fusionarse en la rama `main`. + - **Require status checks to pass before merging:** (Requerir que los checks de estado pasen antes de fusionar) Puedes especificar ciertos checks de estado que deben pasar antes de que se permita la fusión. + +7. **Guarda los Cambios:** Después de configurar las reglas de protección según tus preferencias, haz clic en el botón "Save changes" (Guardar cambios) para aplicar la protección a la rama `main`. + +## Pre-requesito y estructura del terraform en el Repositorio + +- `backend.tf`: Contiene la configuración del backend de Terraform, como el almacenamiento remoto del estado en un proveedor específico, como S3. + IMPORTANTE: Existen variables a nivel de terraform que son importantes configurar para tu entorno, en este archivo estan los comentarios que te indicaran cuales son indispensables de modificar y otras opcionales. +- `hs-juice-shop.tf`: Incluye el código de Terraform para definir la infraestructura de red, Elastic Beanstalk y el pipeline de CodePipeline para el proyecto Juice Shop. +- `provider.tf`: Define el proveedor de Terraform utilizado en este proyecto, que en este caso es AWS. +- `vars.tf`: Define las variables de Terraform utilizadas en el proyecto. + IMPORTANTE: Existen variables a nivel de terraform que son importantes configurar para tu entorno, en este archivo estan los comentarios que te indicaran cuales son indispensables de modificar y otras opcionales. + +## Estructura del GitHub Actions en el Repositorio + +Este es el flujo de trabajo realizado con GitHub Actions para el proceso de gestión de la infraestructura utilizando Terraform dentro de tu proyecto en GitHub. + +### `action-tf-plan.yaml` + +Este archivo de flujo de trabajo, "Pull Request Validation", se activa en cada pull request y se encarga de validar y planificar los cambios de Terraform. Realiza las siguientes acciones: +- **Validación de Terraform**: Ejecuta `terraform validate` para verificar la sintaxis y la configuración de los archivos de Terraform. +- **Planificación de Terraform**: Ejecuta `terraform plan` para generar un plan de los cambios propuestos. +- **Validación del plan**: Revisa el plan de Terraform para garantizar que los cambios sean correctos y no introduzcan errores en la infraestructura existente. +- **Notificación de resultado**: Si el plan es correcto, el flujo de trabajo pasa y el pull request puede ser considerado para ser mergeado. Si se detectan errores, el flujo de trabajo falla y se debe revisar los cambios antes de continuar. -Para desplegar la infraestructura, asegúrate de tener Terraform instalado y configurado con tus credenciales de AWS. Luego, ejecuta los siguientes comandos: +### `action-tf-deploy.yaml` -```bash -terraform init -terraform plan -out=tfplan -terraform apply tfplan +Este archivo de flujo de trabajo, "Deployment on Main Branch", se activa en cada push a la rama `main` y se encarga de aplicar los cambios de Terraform. Realiza las siguientes acciones: +- **Inicialización de Terraform**: Ejecuta `terraform init` para inicializar el directorio de trabajo de Terraform. +- **Planificación de Terraform**: Ejecuta `terraform plan` para generar un plan de los cambios propuestos. +- **Aplicación de cambios**: Ejecuta `terraform apply` para aplicar los cambios de Terraform de manera automática y sin interacción. +- **Notificación de resultado**: Proporciona información sobre el éxito o el fallo de la aplicación de los cambios de Terraform. -## Limpieza +### `action-tf-destroy.yaml` -Recuerda realizar la limpieza de los recursos creados después de finalizar tus pruebas o trabajos con AWS para evitar incurrir en cargos no deseados. Puedes hacerlo ejecutando los siguientes comandos: +Este archivo de flujo de trabajo, "Destroy Infrastructure", se activa manualmente y se encarga de destruir la infraestructura utilizando Terraform. Realiza las siguientes acciones: +- **Inicialización de Terraform**: Ejecuta `terraform init` para inicializar el directorio de trabajo de Terraform. +- **Destrucicón de la infraestructura**: Ejecuta `terraform destroy` para destruir todos los recursos de la infraestructura gestionada por Terraform. +- **Notificación de resultado**: Proporciona información sobre el éxito o el fallo de la destrucción de la infraestructura. -```bash -terraform destroy -``` +### Advertencia de costos sobre el despliegue de Infraestructura en AWS -Este comando eliminará todos los recursos definidos en tu configuración de Terraform. Antes de confirmar la eliminación, revisa cuidadosamente la lista de recursos que se eliminarán. +Este repositorio contiene código Terraform para desplegar una infraestructura en AWS que incluye una VPC, subredes públicas y privadas, un NAT Gateway, Elastic Beanstalk para despliegue de aplicaciones, y un pipeline de CodePipeline para automatizar el despliegue de la aplicación en Elastic Beanstalk. Una vez terminada la practica eliminar los recursos y desplegarlos nuevamente cuando se proponga un nuevo objetivo o continue con el que estaba revisando. +## _Donde esta la aplicación?_ +En las configuraciones de codepipeline definimos cual es el repositorio que utilizaremos para realizar el depsliegue de la aplicacion en Elastic Beanstalk, la utilizada se encuentra definida con la variable `repository` en vars.tf o la puedes cambiar por tu propio fork u otra aplicacion en nodejs 20 en vars.tfvars. \ No newline at end of file diff --git a/backend.tf b/backend.tf index ee78424..67d7236 100644 --- a/backend.tf +++ b/backend.tf @@ -1,7 +1,17 @@ terraform { + # Configuración del backend de Terraform para almacenar el estado remoto en S3 + backend "s3" { + # Nombre del bucket de S3 donde se almacenará el archivo tfstate. + # Cambia el valor a tu propio bucket de S3. bucket = "tf-juice-shop-state-awscd" + + # Nombre del archivo tfstate dentro del bucket de S3. + # Puedes cambiar el valor si deseas un nombre diferente para el archivo tfstate. key = "terraform.tfstate" + + # Región de AWS donde se encuentra el bucket de S3. + # Asegúrate de seleccionar la región correcta para tu bucket de S3. region = "us-east-1" } } \ No newline at end of file diff --git a/hs-juice-shop.tf b/hs-juice-shop.tf index e52745f..bc34739 100644 --- a/hs-juice-shop.tf +++ b/hs-juice-shop.tf @@ -4,33 +4,33 @@ # Define la VPC resource "aws_vpc" "main" { - cidr_block = "10.10.0.0/16" + cidr_block = var.vpc } # Define las subredes públicas resource "aws_subnet" "public1" { vpc_id = aws_vpc.main.id - cidr_block = "10.10.1.0/25" - availability_zone = "us-east-1a" + cidr_block = var.subnetpublica1 + availability_zone = var.availability_zone1a } resource "aws_subnet" "public2" { vpc_id = aws_vpc.main.id - cidr_block = "10.10.2.0/24" - availability_zone = "us-east-1b" + cidr_block = var.subnetpublica2 + availability_zone = var.availability_zone1b } # Define las subredes privadas resource "aws_subnet" "private1" { vpc_id = aws_vpc.main.id - cidr_block = "10.10.3.0/24" - availability_zone = "us-east-1a" + cidr_block = var.subnetprivate1 + availability_zone = var.availability_zone1a } resource "aws_subnet" "private2" { vpc_id = aws_vpc.main.id - cidr_block = "10.10.4.0/24" - availability_zone = "us-east-1b" + cidr_block = var.subnetprivate2 + availability_zone = var.availability_zone1b } # Crea la tabla de rutas para las subredes públicas @@ -108,24 +108,11 @@ resource "aws_eip" "nat" { # Elastic Beanstalk ############################################################# -#resource "aws_s3_bucket" "s3-juice-shop-workshop" { -# bucket = "juice-shop-workshop" -#} - # Define la aplicación Elastic Beanstalk resource "aws_elastic_beanstalk_application" "app_juice_shop" { name = "juice-shop-nodejs-app" } -# Define la versión de la aplicación Elastic Beanstalk -#resource "aws_elastic_beanstalk_application_version" "app_juice_shop_version" { -# application = aws_elastic_beanstalk_application.app_juice_shop.name -# name = "my-app-version" -# description = "My Node.js application version" -# bucket = "aws_s3_bucket.s3-juice-shop-workshop" -# key = "my-bucket/to/your/app.zip" -#} - # Define el entorno de despliegue Elastic Beanstalk resource "aws_elastic_beanstalk_environment" "environment_app_juice_shop" { name = "env-juice-shop-workshop" @@ -159,14 +146,8 @@ resource "aws_elastic_beanstalk_environment" "environment_app_juice_shop" { setting { namespace = "aws:ec2:vpc" name = "ELBSubnets" - value = "${aws_subnet.public1.id},${aws_subnet.public2.id}" + value = "${aws_subnet.public1.id},${aws_subnet.public2.id}" # Las subredes privadas donde deseas desplegar el balanceador } - # Configuración de la versión de la aplicación - #setting { - # namespace = "aws:elasticbeanstalk:application" - # name = "ApplicationVersion" - # value = aws_elastic_beanstalk_application_version.app_juice_shop_version.name - #} setting { namespace = "aws:ec2:vpc" name = "ELBScheme" @@ -202,7 +183,6 @@ resource "aws_elastic_beanstalk_environment" "environment_app_juice_shop" { aws_vpc.main, aws_nat_gateway.main ] - # Especifica la configuración adicional según sea necesario, como variables de entorno, configuración de red, etc. } ############################################################# # AWS CodePipeline @@ -237,7 +217,7 @@ resource "aws_codepipeline" "pipeline-juice-shop-ci-cd" { configuration = { ConnectionArn = aws_codestarconnections_connection.gh-juice-shop.arn - FullRepositoryId = "8infinitecloud/juice-shop" + FullRepositoryId = var.repository BranchName = "master" } } @@ -257,8 +237,6 @@ resource "aws_codepipeline" "pipeline-juice-shop-ci-cd" { configuration = { ApplicationName = aws_elastic_beanstalk_application.app_juice_shop.name EnvironmentName = aws_elastic_beanstalk_environment.environment_app_juice_shop.name -# IgnoreApplicationStopFailures = "false" -# VersionLabel = "AppVersion_${random_id.app_suffix.hex}" } } } diff --git a/provider.tf b/provider.tf index 4ceaa57..cd2f0e3 100644 --- a/provider.tf +++ b/provider.tf @@ -7,6 +7,10 @@ terraform { } } +# Configuración del proveedor AWS para Terraform + provider "aws" { + # Región de AWS donde se desplegarán los recursos. + # Cambia el valor de la región según tu ubicación o requisitos. region = "us-east-1" -} +} \ No newline at end of file diff --git a/vars.tf b/vars.tf new file mode 100644 index 0000000..f787ca1 --- /dev/null +++ b/vars.tf @@ -0,0 +1,51 @@ +############################################################# +# VARIABLES MAIN: HS-JUICE-SHOP +############################################################# + +variable "vpc" { +# vpc: CIDR de la VPC. Ejemplo: "10.10.0.0/23" + type = string + default = "10.10.0.0/23" +} + +variable "subnetpublica1" { +# subnetpublica1: nombre de la primera subred pública. Ejemplo: "subnet-publica-1" + type = string + default = "10.10.0.0/24" +} + +variable "subnetpublica2" { +# subnetpublica1: nombre de la primera subred pública. Ejemplo: "subnet-publica-2" + type = string + default = "10.10.1.0/24" +} + +variable "subnetprivate1" { +# subnetprivate1: nombre de la primera subred privada. Ejemplo: "subnet-privada-1" + type = string + default = "10.10.2.0/24" +} + +variable "subnetprivate2" { +# subnetprivate1: nombre de la primera subred privada. Ejemplo: "subnet-privada-2" + type = string + default = "10.10.3.0/24" +} + +variable "availability_zone1a" { +# availability_zone1a: nombre de la primera zona de disponibilidad. Ejemplo: "us-west-2a" + type = string + default = "us-east-1a" +} + +variable "availability_zone1b" { +# availability_zone1b: nombre de la segunda zona de disponibilidad. Ejemplo: "us-west-2b" + type = string + default = "us-east-1b" +} + +variable "repository" { +# repository: repositorio donde se encuentra nuestra aplicación "Juice Shop" + type = string + default = "8infinitecloud/juice-shop" +} \ No newline at end of file