Merge developer into master: SSH key fixes, tfvars updates, security group fix
This commit is contained in:
+123
-34
@@ -38,9 +38,20 @@ pipelines:
|
|||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- echo "=== Build de proyectosacc (sin deploy) ==="
|
- echo "=== Build de proyectosacc (sin deploy) ==="
|
||||||
- npm ci
|
- |
|
||||||
- npm run build
|
if [ -f package.json ]; then
|
||||||
- ./gradlew clean bootJar
|
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:
|
branches:
|
||||||
developer:
|
developer:
|
||||||
@@ -85,9 +96,20 @@ pipelines:
|
|||||||
name: 04_build
|
name: 04_build
|
||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- npm ci
|
- |
|
||||||
- npm run build
|
if [ -f package.json ]; then
|
||||||
- ./gradlew clean bootJar
|
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:
|
artifacts:
|
||||||
- build/**
|
- build/**
|
||||||
- build/libs/*.jar
|
- build/libs/*.jar
|
||||||
@@ -98,21 +120,44 @@ pipelines:
|
|||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- source scripts/aws-oidc-setup.sh dev
|
- 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:
|
- step:
|
||||||
name: 06_install
|
name: 06_install
|
||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- echo "${DEV_SSH_PRIVATE_KEY_THOTH_PROYECTOSACC}" | base64 -d > ~/.ssh/sacc4_key
|
|
||||||
- chmod 600 ~/.ssh/sacc4_key
|
|
||||||
- |
|
- |
|
||||||
ssh -p "${DEV_SSH_PORT_PROYECTOSACC:-22}" \
|
JAR_LOCAL_PATTERN="build/libs/*.jar"
|
||||||
-i ~/.ssh/sacc4_key \
|
JAR_S3_URI="s3://${DEV_S3_ARTIFACTS_BUCKET}/develop/proyectosacc-app.jar"
|
||||||
-o StrictHostKeyChecking=no \
|
HAS_LOCAL_JAR=false
|
||||||
"${DEV_SERVER_USER_PROYECTOSACC:-thoth}@${DEV_SERVER_IP_PROYECTOSACC}" \
|
if ls ${JAR_LOCAL_PATTERN} >/dev/null 2>&1; then
|
||||||
"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'"
|
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 ${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:
|
- step:
|
||||||
name: 07_deploy
|
name: 07_deploy
|
||||||
@@ -127,12 +172,17 @@ pipelines:
|
|||||||
-i ~/.ssh/sacc4_key \
|
-i ~/.ssh/sacc4_key \
|
||||||
-o StrictHostKeyChecking=no \
|
-o StrictHostKeyChecking=no \
|
||||||
"${DEV_SERVER_USER_PROYECTOSACC:-thoth}@${DEV_SERVER_IP_PROYECTOSACC}" \
|
"${DEV_SERVER_USER_PROYECTOSACC:-thoth}@${DEV_SERVER_IP_PROYECTOSACC}" \
|
||||||
"bash /home/thoth/deploy/setup/deploy.sh"
|
"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'"
|
||||||
- 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 "/*"
|
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_BOT_TOKEN="${DEV_TELEGRAM_BOT_TOKEN}"
|
||||||
- export TELEGRAM_CHAT_ID="${DEV_TELEGRAM_CHAT_ID}"
|
- 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:
|
master:
|
||||||
- step:
|
- step:
|
||||||
@@ -176,9 +226,20 @@ pipelines:
|
|||||||
name: 04_build
|
name: 04_build
|
||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- npm ci
|
- |
|
||||||
- npm run build
|
if [ -f package.json ]; then
|
||||||
- ./gradlew clean bootJar
|
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:
|
artifacts:
|
||||||
- build/**
|
- build/**
|
||||||
- build/libs/*.jar
|
- build/libs/*.jar
|
||||||
@@ -189,21 +250,44 @@ pipelines:
|
|||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- source scripts/aws-oidc-setup.sh prod
|
- 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:
|
- step:
|
||||||
name: 06_install
|
name: 06_install
|
||||||
script:
|
script:
|
||||||
- set -euo pipefail
|
- set -euo pipefail
|
||||||
- echo "${PROD_SSH_PRIVATE_KEY_THOTH_PROYECTOSACC}" | base64 -d > ~/.ssh/sacc4_key
|
|
||||||
- chmod 600 ~/.ssh/sacc4_key
|
|
||||||
- |
|
- |
|
||||||
ssh -p "${PROD_SSH_PORT_PROYECTOSACC:-22}" \
|
JAR_LOCAL_PATTERN="build/libs/*.jar"
|
||||||
-i ~/.ssh/sacc4_key \
|
JAR_S3_URI="s3://${PROD_S3_ARTIFACTS_BUCKET}/main/proyectosacc-app.jar"
|
||||||
-o StrictHostKeyChecking=no \
|
HAS_LOCAL_JAR=false
|
||||||
"${PROD_SERVER_USER_PROYECTOSACC:-thoth}@${PROD_SERVER_IP_PROYECTOSACC}" \
|
if ls ${JAR_LOCAL_PATTERN} >/dev/null 2>&1; then
|
||||||
"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'"
|
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 ${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:
|
- step:
|
||||||
name: 06b_notify_approval
|
name: 06b_notify_approval
|
||||||
@@ -229,9 +313,14 @@ pipelines:
|
|||||||
-i ~/.ssh/sacc4_key \
|
-i ~/.ssh/sacc4_key \
|
||||||
-o StrictHostKeyChecking=no \
|
-o StrictHostKeyChecking=no \
|
||||||
"${PROD_SERVER_USER_PROYECTOSACC:-thoth}@${PROD_SERVER_IP_PROYECTOSACC}" \
|
"${PROD_SERVER_USER_PROYECTOSACC:-thoth}@${PROD_SERVER_IP_PROYECTOSACC}" \
|
||||||
"bash /home/thoth/deploy/setup/deploy.sh"
|
"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'"
|
||||||
- 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 "/*"
|
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_BOT_TOKEN="${PROD_TELEGRAM_BOT_TOKEN}"
|
||||||
- export TELEGRAM_CHAT_ID="${PROD_TELEGRAM_CHAT_ID}"
|
- export TELEGRAM_CHAT_ID="${PROD_TELEGRAM_CHAT_ID}"
|
||||||
- bash scripts/telegram-pipeline-notify.sh success "CloudFront invalidado | Deploy a PROD aprobado y completado"
|
- 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"]
|
availability_zones = ["mx-central-1a", "mx-central-1b"]
|
||||||
ec2_instance_type = "t3.small"
|
ec2_instance_type = "t3.small"
|
||||||
ec2_key_name = "ccsoft-dev-key"
|
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_instance_class = "db.t3.micro"
|
||||||
db_name = "sacc_db_dev"
|
db_name = "sacc_db_dev"
|
||||||
db_username = "sacc_admin_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"]
|
availability_zones = ["mx-central-1a", "mx-central-1b"]
|
||||||
ec2_instance_type = "t3.small"
|
ec2_instance_type = "t3.small"
|
||||||
ec2_key_name = "ccsoft-prod-key"
|
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_instance_class = "db.t3.micro"
|
||||||
db_name = "sacc_db_prod"
|
db_name = "sacc_db_prod"
|
||||||
db_username = "sacc_admin_prod"
|
db_username = "sacc_admin_prod"
|
||||||
|
|||||||
+1
-1
@@ -121,7 +121,7 @@ resource "aws_security_group" "ec2_api" {
|
|||||||
from_port = 22
|
from_port = 22
|
||||||
to_port = 22
|
to_port = 22
|
||||||
protocol = "tcp"
|
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 {
|
ingress {
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ locals {
|
|||||||
# reemplázalo por el UUID exacto del repo ccsoft1/proyectosacc.
|
# reemplázalo por el UUID exacto del repo ccsoft1/proyectosacc.
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
bitbucket_repo_uuid = "{3ceb5bec-0805-4bfb-b891-aaf5626ad7a5}"
|
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
|
# 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" {
|
resource "aws_iam_openid_connect_provider" "bitbucket" {
|
||||||
url = local.bitbucket_oidc_url
|
url = local.bitbucket_oidc_url
|
||||||
|
|
||||||
# Usamos "sts.amazonaws.com" como audience para simplificar la
|
# Bitbucket Cloud usa `ari:cloud:bitbucket::workspace/{uuid}` como audience
|
||||||
# configuración y evitar depender del Workspace UUID de Bitbucket.
|
# fijo en los tokens JWT. Mantenemos `sts.amazonaws.com` por compatibilidad
|
||||||
# Esto requiere configurar "audiences: [sts.amazonaws.com]" en
|
# con configuraciones que lo usen explícitamente.
|
||||||
# bitbucket-pipelines.yml.
|
|
||||||
client_id_list = [
|
client_id_list = [
|
||||||
"sts.amazonaws.com"
|
"sts.amazonaws.com",
|
||||||
|
"ari:cloud:bitbucket::workspace/${local.bitbucket_workspace_uuid}"
|
||||||
]
|
]
|
||||||
|
|
||||||
thumbprint_list = [
|
thumbprint_list = [
|
||||||
@@ -76,8 +79,11 @@ resource "aws_iam_role" "bitbucket_ci_cd" {
|
|||||||
}
|
}
|
||||||
Action = "sts:AssumeRoleWithWebIdentity"
|
Action = "sts:AssumeRoleWithWebIdentity"
|
||||||
Condition = {
|
Condition = {
|
||||||
StringEquals = {
|
"ForAnyValue:StringEquals" = {
|
||||||
"${trimprefix(local.bitbucket_oidc_url, "https://")}:aud" = "sts.amazonaws.com"
|
"${trimprefix(local.bitbucket_oidc_url, "https://")}:aud" = [
|
||||||
|
"sts.amazonaws.com",
|
||||||
|
"ari:cloud:bitbucket::workspace/${local.bitbucket_workspace_uuid}"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
StringLike = {
|
StringLike = {
|
||||||
"${trimprefix(local.bitbucket_oidc_url, "https://")}:sub" = "${local.bitbucket_repo_uuid}:*"
|
"${trimprefix(local.bitbucket_oidc_url, "https://")}:sub" = "${local.bitbucket_repo_uuid}:*"
|
||||||
|
|||||||
Reference in New Issue
Block a user