Skip to content

Commit 21c383a

Browse files
Merge pull request #51 from Maua-Dev/homolog
Implantação do mss em produção
2 parents 9149613 + 82e8d60 commit 21c383a

125 files changed

Lines changed: 3202 additions & 675 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/CD.yml

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
name: CD
32

43
on:
@@ -7,52 +6,83 @@ on:
76
- prod
87
- dev
98
- homolog
9+
- fix/githubActions
1010

1111
workflow_dispatch:
1212

1313
jobs:
1414
DeployToAWS:
1515
environment:
16-
name: ${{ github.ref_name }}
16+
name: ${{ github.ref_name }}
1717
runs-on: ubuntu-latest
1818
permissions:
1919
id-token: write
2020
contents: read
2121

2222
steps:
23-
- uses: actions/checkout@v2
24-
- name: Setup AWS Credentials
25-
uses: aws-actions/configure-aws-credentials@v2
26-
with:
27-
aws-region: ${{ vars.AWS_REGION }}
28-
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/GithubActionsRole
29-
role-session-name: github-action
30-
31-
- name: Setting stage and stack name
32-
run: |
33-
echo "STAGE=${{ github.ref_name }}"
34-
echo "STACK_NAME=ReservationStackScheduleANDCourts${{github.ref_name}}" >> $GITHUB_ENV
35-
36-
- uses: actions/checkout@v3
37-
- uses: actions/setup-python@v4
38-
with:
39-
python-version: '3.9'
40-
41-
- name: Installing Dependencies
42-
run: |
43-
npm install -g aws-cdk
44-
cd iac
45-
pip install -r requirements.txt
46-
47-
- name: DeployWithCDK
48-
run: |
49-
cd iac
50-
cdk synth
51-
cdk deploy --require-approval never
52-
53-
env:
54-
AWS_REGION: ${{ vars.AWS_REGION }}
55-
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
56-
STACK_NAME: ${{ env.STACK_NAME }}
57-
GITHUB_REF_NAME: ${{ github.ref_name }}
58-
GRAPH_MICROSOFT_ENDPOINT: ${{ secrets.GRAPH_MICROSOFT_ENDPOINT }}
23+
- uses: actions/checkout@v2
24+
25+
- name: Set AWS Account ID
26+
run: |
27+
if [[ "${{ github.ref_name }}" == "dev" ]]; then
28+
echo "AWS_ACCOUNT_ID=${{ secrets.AWS_ACCOUNT_ID_DEV }}" >> $GITHUB_ENV
29+
elif [[ "${{ github.ref_name }}" == "homolog" ]]; then
30+
echo "AWS_ACCOUNT_ID=${{ secrets.AWS_ACCOUNT_ID_HOML }}" >> $GITHUB_ENV
31+
elif [[ "${{ github.ref_name }}" == "prod" ]]; then
32+
echo "AWS_ACCOUNT_ID=${{ secrets.AWS_ACCOUNT_ID_PROD }}" >> $GITHUB_ENV
33+
else
34+
echo "Invalid branch name!" && exit 1
35+
fi
36+
37+
- name: Setup AWS Credentials
38+
uses: aws-actions/configure-aws-credentials@v2
39+
with:
40+
aws-region: ${{ vars.AWS_REGION }}
41+
role-to-assume: arn:aws:iam::${{ env.AWS_ACCOUNT_ID }}:role/GithubActionsRole
42+
role-session-name: github-action
43+
44+
- name: Setting stage and stack name
45+
run: |
46+
echo "STAGE=${{ github.ref_name }}"
47+
if [[ "${{ github.ref_name }}" == "prod" ]]; then
48+
echo "STAGE=prod" >> $GITHUB_ENV
49+
elif [[ "${{ github.ref_name }}" == "homolog" ]]; then
50+
echo "STAGE=homolog" >> $GITHUB_ENV
51+
elif [[ "${{ github.ref_name }}" == "dev" ]]; then
52+
echo "STAGE=dev" >> $GITHUB_ENV
53+
elif [[ "${{ github.ref_name }}" == "fix/githubActions" ]]; then
54+
echo "STAGE=dev" >> $GITHUB_ENV
55+
else
56+
echo "Invalid branch name!" && exit 1
57+
fi
58+
echo "STACK_NAME=ReservationStackScheduleANDCourts${{env.STAGE}}" >> $GITHUB_ENV
59+
60+
- uses: actions/checkout@v3
61+
- uses: actions/setup-python@v4
62+
with:
63+
python-version: "3.13"
64+
65+
- name: Installing Dependencies
66+
run: |
67+
npm install -g aws-cdk
68+
cd iac
69+
pip install -r requirements.txt
70+
71+
- name: DeployWithCDK
72+
run: |
73+
cd iac
74+
cdk synth
75+
cdk deploy --require-approval never
76+
77+
env:
78+
AWS_REGION: ${{ vars.AWS_REGION }}
79+
AWS_ACCOUNT_ID: ${{ env.AWS_ACCOUNT_ID }}
80+
STACK_NAME: ${{ env.STACK_NAME }}
81+
GITHUB_REF_NAME: ${{ github.ref_name }}
82+
MSS_NAME: ${{ github.event.repository.name }}
83+
S3_ASSETS_CDN: ${{ vars.S3_ASSETS_CDN }}
84+
AUTH_DEV_SYSTEM_USERPOOL_ARN_DEV: ${{ secrets.AUTH_DEV_SYSTEM_USERPOOL_ARN_DEV }}
85+
FROM_EMAIL: ${{ vars.FROM_EMAIL }}
86+
HIDDEN_COPY: ${{ vars.HIDDEN_COPY }}
87+
REPLY_TO_EMAIL: ${{ vars.REPLY_TO_EMAIL }}
88+
USER_API_URL: ${{ secrets.USER_API_URL }}

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,5 @@ dmypy.json
135135
/.idea/
136136
iac/local/docker/dynamodb/shared-local-instance.db
137137

138-
138+
# MACOS temp files
139139
.DS_Store

iac/adjust_layer_directory.py

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,57 @@
11
import os
22
import shutil
3-
from pathlib import Path
4-
import sys
5-
6-
IAC_DIRECTORY_NAME = "iac"
7-
SOURCE_DIRECTORY_NAME = "src"
8-
LAMBDA_LAYER_PREFIX = os.path.join("python", "src")
9-
10-
11-
def adjust_layer_directory(shared_dir_name: str, destination: str):
12-
# Get the root directory of the source directory
13-
root_directory = Path(__file__).parent.parent
14-
iac_directory = os.path.join(root_directory, IAC_DIRECTORY_NAME)
15-
16-
print(f"Root directory: {root_directory}")
17-
print(f"Root direcotry files: {os.listdir(root_directory)}")
18-
print(f"IaC directory: {iac_directory}")
19-
print(f"IaC directory files: {os.listdir(iac_directory)}")
20-
21-
22-
# Get the destination and source directory
23-
destination_directory = os.path.join(root_directory, IAC_DIRECTORY_NAME, destination)
24-
source_directory = os.path.join(root_directory, SOURCE_DIRECTORY_NAME, shared_dir_name)
25-
26-
# Delete the destination directory if it exists
27-
if os.path.exists(destination_directory):
28-
shutil.rmtree(destination_directory)
29-
30-
# Copy the source directory to the destination directory
31-
shutil.copytree(source_directory, os.path.join(destination_directory, LAMBDA_LAYER_PREFIX, shared_dir_name))
32-
print(
33-
f"Copying files from {source_directory} to {os.path.join(destination_directory, LAMBDA_LAYER_PREFIX, shared_dir_name)}")
34-
35-
3+
import subprocess
4+
from pathlib import Path # Importe a biblioteca pathlib
5+
6+
# --- Configurações ---
7+
BUILD_DIRECTORY = "build"
8+
PYTHON_TOP_LEVEL_DIR = os.path.join(BUILD_DIRECTORY, "python")
9+
REQUIREMENTS_FILE = "requirements-layer.txt"
10+
11+
# --- CONSTRUÇÃO CORRETA DO CAMINHO ---
12+
# Pega o diretório do projeto (a raiz 'reservation_api') subindo um nível a partir do script atual.
13+
PROJECT_ROOT = Path(__file__).parent.parent
14+
# Agora, constrói o caminho para 'src/shared' a partir da raiz do projeto.
15+
SHARED_CODE_SOURCE = os.path.join(PROJECT_ROOT, "src", "shared")
16+
17+
18+
def adjust_layer_directory():
19+
"""
20+
Prepara um diretório 'build' para uma Lambda Layer do AWS CDK.
21+
22+
A função junta o código local compartilhado e as dependências externas (pip)
23+
na estrutura de pastas que a Lambda espera (/python).
24+
"""
25+
26+
# Garante que o build seja sempre limpo, removendo qualquer artefato antigo.
27+
if os.path.exists(BUILD_DIRECTORY):
28+
shutil.rmtree(BUILD_DIRECTORY)
29+
30+
# Cria a estrutura de pastas 'build/python/src/'.
31+
# Isso é necessário para que os imports 'from src.shared...' funcionem na Lambda.
32+
shared_code_intermediate_dir = os.path.join(PYTHON_TOP_LEVEL_DIR, "src")
33+
os.makedirs(shared_code_intermediate_dir)
34+
35+
# Copia o código compartilhado (de 'src/shared') para dentro da estrutura da Layer.
36+
# O resultado final será 'build/python/src/shared'.
37+
print(f"Copiando código de: {SHARED_CODE_SOURCE}") # Adicionado para debug
38+
shared_code_dest = os.path.join(shared_code_intermediate_dir, os.path.basename(SHARED_CODE_SOURCE))
39+
shutil.copytree(SHARED_CODE_SOURCE, shared_code_dest)
40+
41+
# Se o arquivo de dependências existir, instala todas as bibliotecas.
42+
# O arquivo de requirements também precisa ser lido a partir da raiz.
43+
requirements_path = os.path.join(PROJECT_ROOT, REQUIREMENTS_FILE)
44+
if os.path.exists(requirements_path):
45+
# Instala os pacotes diretamente na pasta 'build/python'.
46+
# Isso permite que a Lambda importe as bibliotecas de forma padrão (ex: import requests).
47+
subprocess.check_call(
48+
["pip", "install", "-r", requirements_path, "-t", PYTHON_TOP_LEVEL_DIR, "--no-cache-dir"]
49+
)
50+
else:
51+
# Apenas um aviso caso o arquivo não seja encontrado.
52+
print(f"Aviso: Arquivo '{requirements_path}' não encontrado. Nenhuma dependência externa será instalada.")
53+
54+
55+
# Ponto de entrada do script.
3656
if __name__ == '__main__':
37-
adjust_layer_directory(shared_dir_name="shared", destination="copied_shared")
57+
adjust_layer_directory()

iac/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
print("Starting the CDK")
1111

1212
print("Adjusting the layer directory")
13-
adjust_layer_directory(shared_dir_name="shared", destination="copied_shared")
13+
adjust_layer_directory()
1414
print("Finished adjusting the layer directory")
1515

1616

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
version: '3.8' # The top-level 'version' is obsolete but using a more modern one like 3.8 is fine
2+
3+
services:
4+
minio:
5+
image: minio/minio:latest
6+
container_name: minio-reservation
7+
# ✅ SET credentials for the MinIO server
8+
environment:
9+
MINIO_ROOT_USER: root # If you change any credentials, you have to match it in environments
10+
MINIO_ROOT_PASSWORD: root1234
11+
ports:
12+
- "9000:9000"
13+
- "9001:9001"
14+
volumes:
15+
- minio-data:/data
16+
command: server /data --console-address :9001
17+
18+
create-bucket:
19+
image: minio/mc:latest
20+
depends_on:
21+
- minio
22+
entrypoint: >
23+
/bin/sh -c "
24+
# ✅ Make the script exit on any error
25+
set -e;
26+
27+
# Wait for MinIO to be ready
28+
# Use the more modern 'mc alias set' and provide the credentials
29+
/usr/bin/mc alias set s3 http://minio:9000 root root1234;
30+
31+
# Create the bucket
32+
/usr/bin/mc mb s3/bucket-test;
33+
34+
# Set the policy
35+
/usr/bin/mc policy set public s3/bucket-test;
36+
37+
echo '✅ Bucket created successfully!';
38+
"
39+
40+
volumes:
41+
minio-data:

iac/stacks/bucket_stack.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from aws_cdk import (
22
aws_s3 as s3,
3+
aws_cloudfront as cloudfront,
4+
aws_cloudfront_origins as origins,
35
aws_iam as iam,
46
RemovalPolicy,
5-
Stack,
67
)
78
from constructs import Construct
89
import os
@@ -24,8 +25,19 @@ def __init__(self, scope: Construct, **kwargs) -> None:
2425
stage = 'DEV'
2526

2627
self.bucket = s3.Bucket(
27-
self, f"BACK_S3_REPORT_BUCKET_{stage}",
28-
bucket_name=f"{self.stack_name}-report-bucket{stage}".lower(),
28+
self, f"RESERVATION_BACK_S3_BUCKET_{stage}",
29+
# TODO remover isso quando voltar pra conta nova ou tentar deletar o bucket criado la com power user
30+
bucket_name=f"{self.stack_name}-bucket-{stage}".lower(),
2931
versioned=True,
3032
removal_policy=RemovalPolicy.DESTROY if not (stage == 'PROD') else RemovalPolicy.RETAIN,
33+
block_public_access=s3.BlockPublicAccess.BLOCK_ALL
34+
)
35+
36+
self.distribution = cloudfront.Distribution(
37+
self, f"ReservationBucketDistribution{stage}",
38+
default_behavior=cloudfront.BehaviorOptions(
39+
origin=origins.S3Origin(self.bucket),
40+
viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
41+
),
42+
default_root_object=None # não obrigatório, mas evita erro se não tiver index.html
3143
)

iac/stacks/iac_stack.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from aws_cdk import (
2-
Stack,
2+
Stack, aws_iam
33
)
44
from constructs import Construct
55
from aws_cdk.aws_apigateway import RestApi, Cors
@@ -19,7 +19,7 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
1919
stage = ''
2020
if 'prod' in self.github_ref:
2121
stage = 'PROD'
22-
elif 'homology' in self.github_ref:
22+
elif 'homolog' in self.github_ref:
2323
stage = 'HOMOLOG'
2424
else:
2525
stage = 'DEV'
@@ -55,7 +55,11 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
5555
"DYNAMO_PARTITION_KEY": "PK",
5656
"DYNAMO_SORT_KEY": "SK",
5757
"REGION": self.aws_region,
58-
"GRAPH_MICROSOFT_ENDPOINT": os.getenv("GRAPH_MICROSOFT_ENDPOINT")
58+
"USER_API_URL": os.environ.get("USER_API_URL"),
59+
"S3_BUCKET_NAME": self.s3_bucket.bucket.bucket_name,
60+
"FROM_EMAIL": os.environ.get("FROM_EMAIL"),
61+
"HIDDEN_COPY": os.environ.get("HIDDEN_COPY"),
62+
"S3_ASSETS_CDN": os.environ.get("S3_ASSETS_CDN")
5963
}
6064

6165

@@ -69,4 +73,23 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
6973
for function in self.lambda_stack.functions_that_need_s3_permissions:
7074
self.s3_bucket.bucket.grant_read_write(function)
7175

76+
ses_admin_policy = aws_iam.PolicyStatement(
77+
effect=aws_iam.Effect.ALLOW,
78+
actions=[
79+
"ses:*",
80+
],
81+
resources=[
82+
"*"
83+
]
84+
)
85+
86+
functions_that_need_ses_permissions = [
87+
self.lambda_stack.delete_booking
88+
]
89+
90+
for f in functions_that_need_ses_permissions:
91+
f.add_environment("HIDDEN_COPY", os.environ.get("HIDDEN_COPY"))
92+
f.add_environment("FROM_EMAIL", os.environ.get("FROM_EMAIL"))
93+
f.add_environment("REPLY_TO_EMAIL", os.environ.get("REPLY_TO_EMAIL"))
94+
f.add_to_role_policy(ses_admin_policy)
7295

0 commit comments

Comments
 (0)