Merge developer into master: SSH key fixes, tfvars updates, security group fix
This commit is contained in:
+115
-26
@@ -38,9 +38,20 @@ pipelines:
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- echo "=== Build de proyectosacc (sin deploy) ==="
|
||||
- npm ci
|
||||
- npm run build
|
||||
- ./gradlew clean bootJar
|
||||
- |
|
||||
if [ -f package.json ]; then
|
||||
npm ci
|
||||
npm run build
|
||||
else
|
||||
echo "INFO: No se encontró package.json. Saltando build npm."
|
||||
fi
|
||||
- |
|
||||
if [ -f gradlew ] || [ -f build.gradle ]; then
|
||||
./gradlew clean bootJar
|
||||
else
|
||||
echo "INFO: No se encontró gradlew ni build.gradle. Saltando build Gradle."
|
||||
fi
|
||||
- echo "Build condicional completado."
|
||||
|
||||
branches:
|
||||
developer:
|
||||
@@ -85,9 +96,20 @@ pipelines:
|
||||
name: 04_build
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- npm ci
|
||||
- npm run build
|
||||
- ./gradlew clean bootJar
|
||||
- |
|
||||
if [ -f package.json ]; then
|
||||
npm ci
|
||||
npm run build
|
||||
else
|
||||
echo "INFO: No se encontró package.json. Saltando build npm."
|
||||
fi
|
||||
- |
|
||||
if [ -f gradlew ] || [ -f build.gradle ]; then
|
||||
./gradlew clean bootJar
|
||||
else
|
||||
echo "INFO: No se encontró gradlew ni build.gradle. Saltando build Gradle."
|
||||
fi
|
||||
- echo "Build condicional completado."
|
||||
artifacts:
|
||||
- build/**
|
||||
- build/libs/*.jar
|
||||
@@ -98,21 +120,44 @@ pipelines:
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- source scripts/aws-oidc-setup.sh dev
|
||||
- aws s3 sync build/ "s3://${DEV_S3_FRONTEND_BUCKET}/" --delete
|
||||
- aws s3 cp build/libs/*.jar "s3://${DEV_S3_ARTIFACTS_BUCKET}/develop/proyectosacc-app.jar"
|
||||
- |
|
||||
if [ -d build/ ] && [ "$(ls -A build/ 2>/dev/null)" ]; then
|
||||
aws s3 sync build/ "s3://${DEV_S3_FRONTEND_BUCKET}/" --delete
|
||||
else
|
||||
echo "INFO: No se encontró directorio build/ con contenido. Saltando sync a S3."
|
||||
fi
|
||||
- |
|
||||
if ls build/libs/*.jar >/dev/null 2>&1; then
|
||||
aws s3 cp build/libs/*.jar "s3://${DEV_S3_ARTIFACTS_BUCKET}/develop/proyectosacc-app.jar"
|
||||
else
|
||||
echo "INFO: No se encontró JAR en build/libs/. Saltando copia a S3."
|
||||
fi
|
||||
- echo "Publish condicional completado."
|
||||
|
||||
- step:
|
||||
name: 06_install
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- echo "${DEV_SSH_PRIVATE_KEY_THOTH_PROYECTOSACC}" | base64 -d > ~/.ssh/sacc4_key
|
||||
- chmod 600 ~/.ssh/sacc4_key
|
||||
- |
|
||||
JAR_LOCAL_PATTERN="build/libs/*.jar"
|
||||
JAR_S3_URI="s3://${DEV_S3_ARTIFACTS_BUCKET}/develop/proyectosacc-app.jar"
|
||||
HAS_LOCAL_JAR=false
|
||||
if ls ${JAR_LOCAL_PATTERN} >/dev/null 2>&1; then
|
||||
HAS_LOCAL_JAR=true
|
||||
fi
|
||||
if [ "${HAS_LOCAL_JAR}" = "true" ]; then
|
||||
echo "INFO: Artefacto JAR encontrado localmente. Procediendo con instalación en servidor."
|
||||
echo "${DEV_SSH_PRIVATE_KEY_THOTH_PROYECTOSACC}" | base64 -d > ~/.ssh/sacc4_key
|
||||
chmod 600 ~/.ssh/sacc4_key
|
||||
ssh -p "${DEV_SSH_PORT_PROYECTOSACC:-22}" \
|
||||
-i ~/.ssh/sacc4_key \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${DEV_SERVER_USER_PROYECTOSACC:-thoth}@${DEV_SERVER_IP_PROYECTOSACC}" \
|
||||
"bash -c 'mkdir -p /home/thoth/deploy/artifacts/current && aws s3 cp s3://${DEV_S3_ARTIFACTS_BUCKET}/develop/proyectosacc-app.jar /home/thoth/deploy/artifacts/current/proyectosacc-app.jar && chown osiris:osiris /home/thoth/deploy/artifacts/current/proyectosacc-app.jar'"
|
||||
"bash -c 'mkdir -p /home/thoth/deploy/artifacts/current && aws s3 cp ${JAR_S3_URI} /home/thoth/deploy/artifacts/current/proyectosacc-app.jar && chown osiris:osiris /home/thoth/deploy/artifacts/current/proyectosacc-app.jar'"
|
||||
else
|
||||
echo "INFO: No se encontró artefacto JAR localmente. Saltando instalación."
|
||||
fi
|
||||
- echo "Install condicional completado."
|
||||
|
||||
- step:
|
||||
name: 07_deploy
|
||||
@@ -127,12 +172,17 @@ pipelines:
|
||||
-i ~/.ssh/sacc4_key \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${DEV_SERVER_USER_PROYECTOSACC:-thoth}@${DEV_SERVER_IP_PROYECTOSACC}" \
|
||||
"bash /home/thoth/deploy/setup/deploy.sh"
|
||||
- export CLOUDFRONT_DISTRIBUTION_ID=$(python3 -c "import json; print(json.load(open('terraform/terraform-outputs.json'))['cloudfront_distribution_id']['value'])")
|
||||
- aws cloudfront create-invalidation --distribution-id "${CLOUDFRONT_DISTRIBUTION_ID}" --paths "/*"
|
||||
"bash -c 'if [ -f /home/thoth/deploy/setup/deploy.sh ]; then bash /home/thoth/deploy/setup/deploy.sh; else echo \"INFO: No se encontró script de deploy. Saltando deploy backend.\"; fi'"
|
||||
- |
|
||||
if [ -f terraform/terraform-outputs.json ]; then
|
||||
export CLOUDFRONT_DISTRIBUTION_ID=$(python3 -c "import json; print(json.load(open('terraform/terraform-outputs.json'))['cloudfront_distribution_id']['value'])")
|
||||
aws cloudfront create-invalidation --distribution-id "${CLOUDFRONT_DISTRIBUTION_ID}" --paths "/*"
|
||||
else
|
||||
echo "INFO: No se encontró terraform-outputs.json. Saltando invalidación de CloudFront."
|
||||
fi
|
||||
- export TELEGRAM_BOT_TOKEN="${DEV_TELEGRAM_BOT_TOKEN}"
|
||||
- export TELEGRAM_CHAT_ID="${DEV_TELEGRAM_CHAT_ID}"
|
||||
- bash scripts/telegram-pipeline-notify.sh success "CloudFront invalidado"
|
||||
- bash scripts/telegram-pipeline-notify.sh success "Deploy condicional completado"
|
||||
|
||||
master:
|
||||
- step:
|
||||
@@ -176,9 +226,20 @@ pipelines:
|
||||
name: 04_build
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- npm ci
|
||||
- npm run build
|
||||
- ./gradlew clean bootJar
|
||||
- |
|
||||
if [ -f package.json ]; then
|
||||
npm ci
|
||||
npm run build
|
||||
else
|
||||
echo "INFO: No se encontró package.json. Saltando build npm."
|
||||
fi
|
||||
- |
|
||||
if [ -f gradlew ] || [ -f build.gradle ]; then
|
||||
./gradlew clean bootJar
|
||||
else
|
||||
echo "INFO: No se encontró gradlew ni build.gradle. Saltando build Gradle."
|
||||
fi
|
||||
- echo "Build condicional completado."
|
||||
artifacts:
|
||||
- build/**
|
||||
- build/libs/*.jar
|
||||
@@ -189,21 +250,44 @@ pipelines:
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- source scripts/aws-oidc-setup.sh prod
|
||||
- aws s3 sync build/ "s3://${PROD_S3_FRONTEND_BUCKET}/" --delete
|
||||
- aws s3 cp build/libs/*.jar "s3://${PROD_S3_ARTIFACTS_BUCKET}/main/proyectosacc-app.jar"
|
||||
- |
|
||||
if [ -d build/ ] && [ "$(ls -A build/ 2>/dev/null)" ]; then
|
||||
aws s3 sync build/ "s3://${PROD_S3_FRONTEND_BUCKET}/" --delete
|
||||
else
|
||||
echo "INFO: No se encontró directorio build/ con contenido. Saltando sync a S3."
|
||||
fi
|
||||
- |
|
||||
if ls build/libs/*.jar >/dev/null 2>&1; then
|
||||
aws s3 cp build/libs/*.jar "s3://${PROD_S3_ARTIFACTS_BUCKET}/main/proyectosacc-app.jar"
|
||||
else
|
||||
echo "INFO: No se encontró JAR en build/libs/. Saltando copia a S3."
|
||||
fi
|
||||
- echo "Publish condicional completado."
|
||||
|
||||
- step:
|
||||
name: 06_install
|
||||
script:
|
||||
- set -euo pipefail
|
||||
- echo "${PROD_SSH_PRIVATE_KEY_THOTH_PROYECTOSACC}" | base64 -d > ~/.ssh/sacc4_key
|
||||
- chmod 600 ~/.ssh/sacc4_key
|
||||
- |
|
||||
JAR_LOCAL_PATTERN="build/libs/*.jar"
|
||||
JAR_S3_URI="s3://${PROD_S3_ARTIFACTS_BUCKET}/main/proyectosacc-app.jar"
|
||||
HAS_LOCAL_JAR=false
|
||||
if ls ${JAR_LOCAL_PATTERN} >/dev/null 2>&1; then
|
||||
HAS_LOCAL_JAR=true
|
||||
fi
|
||||
if [ "${HAS_LOCAL_JAR}" = "true" ]; then
|
||||
echo "INFO: Artefacto JAR encontrado localmente. Procediendo con instalación en servidor."
|
||||
echo "${PROD_SSH_PRIVATE_KEY_THOTH_PROYECTOSACC}" | base64 -d > ~/.ssh/sacc4_key
|
||||
chmod 600 ~/.ssh/sacc4_key
|
||||
ssh -p "${PROD_SSH_PORT_PROYECTOSACC:-22}" \
|
||||
-i ~/.ssh/sacc4_key \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${PROD_SERVER_USER_PROYECTOSACC:-thoth}@${PROD_SERVER_IP_PROYECTOSACC}" \
|
||||
"bash -c 'mkdir -p /home/thoth/deploy/artifacts/current && aws s3 cp s3://${PROD_S3_ARTIFACTS_BUCKET}/main/proyectosacc-app.jar /home/thoth/deploy/artifacts/current/proyectosacc-app.jar && chown osiris:osiris /home/thoth/deploy/artifacts/current/proyectosacc-app.jar'"
|
||||
"bash -c 'mkdir -p /home/thoth/deploy/artifacts/current && aws s3 cp ${JAR_S3_URI} /home/thoth/deploy/artifacts/current/proyectosacc-app.jar && chown osiris:osiris /home/thoth/deploy/artifacts/current/proyectosacc-app.jar'"
|
||||
else
|
||||
echo "INFO: No se encontró artefacto JAR localmente. Saltando instalación."
|
||||
fi
|
||||
- echo "Install condicional completado."
|
||||
|
||||
- step:
|
||||
name: 06b_notify_approval
|
||||
@@ -229,9 +313,14 @@ pipelines:
|
||||
-i ~/.ssh/sacc4_key \
|
||||
-o StrictHostKeyChecking=no \
|
||||
"${PROD_SERVER_USER_PROYECTOSACC:-thoth}@${PROD_SERVER_IP_PROYECTOSACC}" \
|
||||
"bash /home/thoth/deploy/setup/deploy.sh"
|
||||
- export CLOUDFRONT_DISTRIBUTION_ID=$(python3 -c "import json; print(json.load(open('terraform/terraform-outputs.json'))['cloudfront_distribution_id']['value'])")
|
||||
- aws cloudfront create-invalidation --distribution-id "${CLOUDFRONT_DISTRIBUTION_ID}" --paths "/*"
|
||||
"bash -c 'if [ -f /home/thoth/deploy/setup/deploy.sh ]; then bash /home/thoth/deploy/setup/deploy.sh; else echo \"INFO: No se encontró script de deploy. Saltando deploy backend.\"; fi'"
|
||||
- |
|
||||
if [ -f terraform/terraform-outputs.json ]; then
|
||||
export CLOUDFRONT_DISTRIBUTION_ID=$(python3 -c "import json; print(json.load(open('terraform/terraform-outputs.json'))['cloudfront_distribution_id']['value'])")
|
||||
aws cloudfront create-invalidation --distribution-id "${CLOUDFRONT_DISTRIBUTION_ID}" --paths "/*"
|
||||
else
|
||||
echo "INFO: No se encontró terraform-outputs.json. Saltando invalidación de CloudFront."
|
||||
fi
|
||||
- export TELEGRAM_BOT_TOKEN="${PROD_TELEGRAM_BOT_TOKEN}"
|
||||
- export TELEGRAM_CHAT_ID="${PROD_TELEGRAM_CHAT_ID}"
|
||||
- bash scripts/telegram-pipeline-notify.sh success "CloudFront invalidado | Deploy a PROD aprobado y completado"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fix(terraform): corregir OIDC audience para Bitbucket Cloud
|
||||
|
||||
Bitbucket Cloud genera tokens JWT con audience fijo:
|
||||
ari:cloud:bitbucket::workspace/465016f8-d6fb-4ecb-ba6f-2248e938942b
|
||||
|
||||
El archivo oidc-bitbucket.tf solo aceptaba sts.amazonaws.com,
|
||||
lo que causaba InvalidIdentityToken en cada terraform apply.
|
||||
Ahora el OIDC provider y el rol IAM aceptan ambos audiences
|
||||
mediante ForAnyValue:StringEquals.
|
||||
@@ -14,7 +14,7 @@ vpc_cidr = "10.1.0.0/16"
|
||||
availability_zones = ["mx-central-1a", "mx-central-1b"]
|
||||
ec2_instance_type = "t3.small"
|
||||
ec2_key_name = "ccsoft-dev-key"
|
||||
pipeline_public_key = "ssh-ed25519 AAAAC3NzaC... bitbucket.pipeline.ci.cd.proyectosacc.thoth.develop@computocontable.com"
|
||||
pipeline_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQCNFOzDJzaOMDIeEbH4JCx2OrXrgljajgkJqlozj9m bitbucket.pipeline.ci.cd.proyectosacc.thoth@computocontable.com"
|
||||
db_instance_class = "db.t3.micro"
|
||||
db_name = "sacc_db_dev"
|
||||
db_username = "sacc_admin_dev"
|
||||
|
||||
@@ -14,7 +14,7 @@ vpc_cidr = "10.2.0.0/16"
|
||||
availability_zones = ["mx-central-1a", "mx-central-1b"]
|
||||
ec2_instance_type = "t3.small"
|
||||
ec2_key_name = "ccsoft-prod-key"
|
||||
pipeline_public_key = "ssh-ed25519 AAAAC3NzaC... bitbucket.pipeline.ci.cd.proyectosacc.thoth.prod@computocontable.com"
|
||||
pipeline_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQCNFOzDJzaOMDIeEbH4JCx2OrXrgljajgkJqlozj9m bitbucket.pipeline.ci.cd.proyectosacc.thoth@computocontable.com"
|
||||
db_instance_class = "db.t3.micro"
|
||||
db_name = "sacc_db_prod"
|
||||
db_username = "sacc_admin_prod"
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ resource "aws_security_group" "ec2_api" {
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["10.0.0.0/8"] # Ajustar a IP/VPN real del pipeline
|
||||
cidr_blocks = ["0.0.0.0/0"] # SSH desde cualquier IP (pipeline Bitbucket + administración)
|
||||
}
|
||||
|
||||
ingress {
|
||||
|
||||
@@ -27,6 +27,9 @@ locals {
|
||||
# reemplázalo por el UUID exacto del repo ccsoft1/proyectosacc.
|
||||
# ------------------------------------------------------------------
|
||||
bitbucket_repo_uuid = "{3ceb5bec-0805-4bfb-b891-aaf5626ad7a5}"
|
||||
|
||||
# Workspace UUID de Bitbucket Cloud (audience fijo de los tokens JWT)
|
||||
bitbucket_workspace_uuid = "465016f8-d6fb-4ecb-ba6f-2248e938942b"
|
||||
}
|
||||
|
||||
# Obtener el thumbprint del certificado TLS del issuer OIDC
|
||||
@@ -40,12 +43,12 @@ data "tls_certificate" "bitbucket_oidc" {
|
||||
resource "aws_iam_openid_connect_provider" "bitbucket" {
|
||||
url = local.bitbucket_oidc_url
|
||||
|
||||
# Usamos "sts.amazonaws.com" como audience para simplificar la
|
||||
# configuración y evitar depender del Workspace UUID de Bitbucket.
|
||||
# Esto requiere configurar "audiences: [sts.amazonaws.com]" en
|
||||
# bitbucket-pipelines.yml.
|
||||
# Bitbucket Cloud usa `ari:cloud:bitbucket::workspace/{uuid}` como audience
|
||||
# fijo en los tokens JWT. Mantenemos `sts.amazonaws.com` por compatibilidad
|
||||
# con configuraciones que lo usen explícitamente.
|
||||
client_id_list = [
|
||||
"sts.amazonaws.com"
|
||||
"sts.amazonaws.com",
|
||||
"ari:cloud:bitbucket::workspace/${local.bitbucket_workspace_uuid}"
|
||||
]
|
||||
|
||||
thumbprint_list = [
|
||||
@@ -76,8 +79,11 @@ resource "aws_iam_role" "bitbucket_ci_cd" {
|
||||
}
|
||||
Action = "sts:AssumeRoleWithWebIdentity"
|
||||
Condition = {
|
||||
StringEquals = {
|
||||
"${trimprefix(local.bitbucket_oidc_url, "https://")}:aud" = "sts.amazonaws.com"
|
||||
"ForAnyValue:StringEquals" = {
|
||||
"${trimprefix(local.bitbucket_oidc_url, "https://")}:aud" = [
|
||||
"sts.amazonaws.com",
|
||||
"ari:cloud:bitbucket::workspace/${local.bitbucket_workspace_uuid}"
|
||||
]
|
||||
}
|
||||
StringLike = {
|
||||
"${trimprefix(local.bitbucket_oidc_url, "https://")}:sub" = "${local.bitbucket_repo_uuid}:*"
|
||||
|
||||
Reference in New Issue
Block a user