diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..4f3d655 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,33 @@ +# シェルスクリプトは常にLFを使用 +*.sh text eol=lf + +# PowerShellスクリプトは常にCRLFを使用 +*.ps1 text eol=crlf + +# その他のテキストファイル +*.txt text eol=lf +*.md text eol=lf +*.yml text eol=lf +*.yaml text eol=lf +*.json text eol=lf +*.py text eol=lf +*.js text eol=lf +*.ts text eol=lf +*.html text eol=lf +*.css text eol=lf +*.xml text eol=lf + +# バイナリファイル +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.pdf binary +*.zip binary +*.tar binary +*.gz binary +*.exe binary +*.dll binary +*.so binary +*.dylib binary \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..d4d203f --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,101 @@ +name: Deploy to AWS CloudFormation + +on: + push: + branches: + - main + - deploy + +env: + AWS_REGION: ap-northeast-1 + PROJECT_NAME: LambdaFramework + +permissions: + id-token: write + contents: read + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Debug AWS Role ARN + run: | + echo "Current branch: ${{ github.ref }}" + echo "Branch condition: ${{ github.ref == 'refs/heads/main' }}" + echo "Using role ARN: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_ARN_PROD || secrets.AWS_ROLE_ARN_DEV }}" + echo "AWS_ROLE_ARN_DEV exists: ${{ secrets.AWS_ROLE_ARN_DEV != '' }}" + echo "AWS_ROLE_ARN_PROD exists: ${{ secrets.AWS_ROLE_ARN_PROD != '' }}" + echo "AWS_ROLE_ARN_DEV length: ${{ secrets.AWS_ROLE_ARN_DEV != '' && 'non-empty' || 'empty' }}" + echo "AWS_ROLE_ARN_PROD length: ${{ secrets.AWS_ROLE_ARN_PROD != '' && 'non-empty' || 'empty' }}" + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ github.ref == 'refs/heads/main' && secrets.AWS_ROLE_ARN_PROD || secrets.AWS_ROLE_ARN_DEV }} + aws-region: ${{ env.AWS_REGION }} + + - name: Validate SAM template + run: | + # AWS認証情報の確認 + aws sts get-caller-identity + echo "AWS Region: $AWS_REGION" + sam validate + env: + AWS_REGION: ${{ env.AWS_REGION }} + + - name: Deploy with SAM + run: | + STACK_NAME="LambdaFramework" + # ブランチに基づいて環境設定を決定 + if [ "${{ github.ref }}" = "refs/heads/main" ]; then + ENVIRONMENT="production" + S3_BUCKET="${{ vars.S3_BUCKET_PROD }}" + else + ENVIRONMENT="development" + S3_BUCKET="${{ vars.S3_BUCKET_DEV }}" + fi + + echo "Deploying to environment: $ENVIRONMENT" + echo "Stack name: $STACK_NAME" + echo "AWS Region: $AWS_REGION" + echo "S3 Bucket: $S3_BUCKET" + + sam build + sam deploy --no-confirm-changeset --no-fail-on-empty-changeset \ + --stack-name $STACK_NAME \ + --s3-bucket $S3_BUCKET \ + --parameter-overrides ProjectName=${{ env.PROJECT_NAME }} Environment=$ENVIRONMENT + env: + AWS_REGION: ${{ env.AWS_REGION }} + SAM_CLI_TELEMETRY: 0 + + - name: Deploy status + if: always() + run: | + # ブランチに基づいて環境設定を決定 + if [ "${{ github.ref }}" = "refs/heads/main" ]; then + STACK_NAME="lambda-framework-prod" + ENVIRONMENT="production" + else + STACK_NAME="lambda-framework-dev" + ENVIRONMENT="development" + fi + + echo "Deployment completed for branch: ${{ github.ref }}" + echo "Stack name: $STACK_NAME" + echo "Environment: $ENVIRONMENT" + echo "Commit: ${{ github.sha }}" \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..22d1d12 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "cfn-lint.executablePath": "cfn-lint", + "cfn-lint.enable": true, + "yaml.validate": true, + "yaml.schemas": { + "https://raw.githubusercontent.com/aws/aws-sam-cli/master/samcli/local/schema/schema.json": "template.yaml" + } +} \ No newline at end of file diff --git a/GITHUB_SECRETS_SETUP.md b/GITHUB_SECRETS_SETUP.md new file mode 100644 index 0000000..a562a50 --- /dev/null +++ b/GITHUB_SECRETS_SETUP.md @@ -0,0 +1,243 @@ +# GitHub Secrets Setup Guide + +## 概要 +このドキュメントでは、GitHub ActionsでAWS CloudFormationにデプロイするために必要なGitHub SecretsとIAMロールの設定手順を説明します。 + +## 必要なGitHub Secrets + +### 1. AWS_ROLE_ARN_DEV (開発環境用) +- **説明**: 開発環境(deployブランチ)で使用するIAMロールのARN +- **例**: `arn:aws:iam::123456789012:role/LambdaFramework-github-actions-role` + +### 2. AWS_ROLE_ARN_PROD (本番環境用) +- **説明**: 本番環境(mainブランチ)で使用するIAMロールのARN +- **例**: `arn:aws:iam::123456789012:role/LambdaFramework-github-actions-role` + +## IAMロールとOIDCプロバイダーの設定 + +### 1. OIDCプロバイダーの作成 + +#### 開発環境用AWSアカウント +```bash +# OIDCプロバイダーの作成 +aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 + +# 作成されたOIDCプロバイダーのARNを確認 +aws iam list-open-id-connect-providers +``` + +#### 本番環境用AWSアカウント +```bash +# OIDCプロバイダーの作成 +aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 + +# 作成されたOIDCプロバイダーのARNを確認 +aws iam list-open-id-connect-providers +``` + +### 2. IAMロールの作成 + +#### 開発環境用IAMロール +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::YOUR_DEV_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "token.actions.githubusercontent.com:aud": "sts.amazonaws.com", + "token.actions.githubusercontent.com:sub": "repo:cloudnative-co/python-lambda-frame:ref:refs/heads/deploy" + } + } + } + ] +} +``` + +#### 本番環境用IAMロール +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::YOUR_PROD_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "token.actions.githubusercontent.com:aud": "sts.amazonaws.com", + "token.actions.githubusercontent.com:sub": "repo:cloudnative-co/python-lambda-frame:ref:refs/heads/main" + } + } + } + ] +} +``` + +### 3. IAMポリシーの作成 + +#### 開発環境用IAMポリシー +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "cloudformation:*", + "s3:*", + "lambda:*", + "iam:*", + "logs:*" + ], + "Resource": "*" + } + ] +} +``` + +#### 本番環境用IAMポリシー +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "cloudformation:*", + "s3:*", + "lambda:*", + "iam:*", + "logs:*" + ], + "Resource": "*" + } + ] +} +``` + +## トラブルシューティング + +### 1. "Request ARN is invalid" エラーの解決 + +#### A. OIDCプロバイダーの確認 +```bash +# OIDCプロバイダーが存在するか確認 +aws iam list-open-id-connect-providers + +# 特定のOIDCプロバイダーの詳細を確認 +aws iam get-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com +``` + +#### B. IAMロールの信頼関係の確認 +```bash +# IAMロールの詳細を確認 +aws iam get-role --role-name LambdaFramework-github-actions-role + +# 信頼関係(Trust Policy)を確認 +aws iam get-role-policy --role-name LambdaFramework-github-actions-role --policy-name trust-policy +``` + +#### C. 正しいロールARNの確認 +```bash +# 利用可能なIAMロールを一覧表示 +aws iam list-roles --query 'Roles[?contains(RoleName, `LambdaFramework`)].RoleName' --output table +``` + +### 2. よくある問題と解決方法 + +#### A. OIDCプロバイダーが存在しない +```bash +# OIDCプロバイダーを作成 +aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 +``` + +#### B. 信頼関係が正しくない +- IAMロールの信頼関係で、正しいOIDCプロバイダーARNを指定 +- 正しいリポジトリ名とブランチ名を指定 + +#### C. GitHub Secretsが設定されていない +- GitHubリポジトリのSettings → Secrets and variables → Actions +- `AWS_ROLE_ARN_DEV`と`AWS_ROLE_ARN_PROD`を設定 + +## 設定手順 + +### 1. AWS CLIでOIDCプロバイダーを作成 +```bash +# 開発環境用 +aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 + +# 本番環境用 +aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 +``` + +### 2. IAMロールを作成 +```bash +# 開発環境用ロール +aws iam create-role --role-name LambdaFramework-github-actions-role --assume-role-policy-document file://trust-policy-dev.json + +# 本番環境用ロール +aws iam create-role --role-name LambdaFramework-github-actions-role --assume-role-policy-document file://trust-policy-prod.json +``` + +### 3. IAMポリシーをアタッチ +```bash +# 開発環境用ポリシー +aws iam put-role-policy --role-name LambdaFramework-github-actions-role --policy-name LambdaFramework-github-actions-policy --policy-document file://policy-dev.json + +# 本番環境用ポリシー +aws iam put-role-policy --role-name LambdaFramework-github-actions-role --policy-name LambdaFramework-github-actions-policy --policy-document file://policy-prod.json +``` + +### 4. GitHub Secretsを設定 +1. GitHubリポジトリにアクセス +2. Settings → Secrets and variables → Actions +3. New repository secretをクリック +4. `AWS_ROLE_ARN_DEV`と`AWS_ROLE_ARN_PROD`を設定 + +## デプロイ環境マッピング + +| ブランチ | 環境 | AWSロール | GitHub Secret | +|---------|------|-----------|---------------| +| main | production | LambdaFramework-github-actions-role | AWS_ROLE_ARN_PROD | +| deploy | development | LambdaFramework-github-actions-role | AWS_ROLE_ARN_DEV | + +## ローカルデプロイコマンド + +### 開発環境 +```bash +./deploy-env.sh development +``` + +### 本番環境 +```bash +./deploy-env.sh production +``` + +### PowerShell版 +```powershell +.\deploy-env.ps1 development +.\deploy-env.ps1 production +``` \ No newline at end of file diff --git a/README.md b/README.md index 052c993..00e7dd3 100644 --- a/README.md +++ b/README.md @@ -1 +1,38 @@ -# python-lambda-frame \ No newline at end of file +# Python Lambda Framework + +AWS Lambda Layer for Python development with comprehensive schema support. + +## Features + +- **Multi-Service Support**: Comprehensive AWS service schemas +- **Environment Management**: Multi-account deployment support +- **CI/CD Integration**: GitHub Actions with OIDC authentication +- **Flexible Configuration**: Environment-specific S3 buckets and IAM roles + +## Quick Start + +1. **Setup IAM Roles and OIDC**: + ```bash + ./create_role.sh + # or + ./create_role.ps1 + ``` + +2. **Deploy to AWS**: + ```bash + sam build + sam deploy + ``` + +## GitHub Actions + +This project includes automated CI/CD pipeline with: +- Multi-branch deployment (`main` → production, `deploy` → development) +- OIDC authentication for secure AWS access +- Environment-specific configurations + +## Updated: 2025-07-31 + +Latest deployment test with OIDC and multi-environment setup. +Fixed IAM role ARN configuration for production environment. +Fixed IAM role ARN format with double colon (::) for correct AWS format. \ No newline at end of file diff --git a/create_role.ps1 b/create_role.ps1 new file mode 100644 index 0000000..b95318e --- /dev/null +++ b/create_role.ps1 @@ -0,0 +1,1343 @@ +# PowerShellスクリプト: AWS CLIとSAM CLIのアクセス確認、GitHubユーザー情報取得、OIDC用IAMロール作成、GitHub Secrets自動登録 + +# 色付き出力用の関数 +function Write-Info { + param([string]$Message) + Write-Host "[INFO] $Message" -ForegroundColor Blue +} + +function Write-Success { + param([string]$Message) + Write-Host "[SUCCESS] $Message" -ForegroundColor Green +} + +function Write-Error { + param([string]$Message) + Write-Host "[ERROR] $Message" -ForegroundColor Red +} + +function Write-Warning { + param([string]$Message) + Write-Host "[WARNING] $Message" -ForegroundColor Yellow +} + +# 1. AWS CLIの確認 +Write-Info "AWS CLIの確認中..." +try { + $awsVersion = aws --version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "AWS CLIが見つかりました: $awsVersion" + } else { + throw "AWS CLIが見つかりません" + } +} catch { + Write-Error "AWS CLIがインストールされていません" + exit 1 +} + +# 2. SAM CLIの確認 +Write-Info "SAM CLIの確認中..." +$SAM_CMD = $null + +# Windows環境でのSAM CLI確認 +Write-Info "Windows環境を検出しました" +try { + # sam.cmdを優先して確認 + Write-Info "sam.cmdの確認中..." + if (Get-Command sam.cmd -ErrorAction SilentlyContinue) { + try { + $samVersion = sam.cmd --version 2>$null + if ($LASTEXITCODE -eq 0) { + $SAM_CMD = "sam.cmd" + Write-Success "SAM CLIが見つかりました: sam.cmd ($samVersion)" + } else { + Write-Info "sam.cmdは存在しますが実行できません" + } + } catch { + Write-Info "sam.cmdの実行中にエラーが発生しました: $_" + } + } else { + Write-Info "sam.cmdが見つかりません" + } + + # sam.exeを確認 + if (-not $SAM_CMD) { + Write-Info "sam.exeの確認中..." + if (Get-Command sam.exe -ErrorAction SilentlyContinue) { + try { + $samVersion = sam.exe --version 2>$null + if ($LASTEXITCODE -eq 0) { + $SAM_CMD = "sam.exe" + Write-Success "SAM CLIが見つかりました: sam.exe ($samVersion)" + } else { + Write-Info "sam.exeは存在しますが実行できません" + } + } catch { + Write-Info "sam.exeの実行中にエラーが発生しました: $_" + } + } else { + Write-Info "sam.exeが見つかりません" + } + } + + # 通常のsamコマンドを確認 + if (-not $SAM_CMD) { + Write-Info "samの確認中..." + if (Get-Command sam -ErrorAction SilentlyContinue) { + try { + $samVersion = sam --version 2>$null + if ($LASTEXITCODE -eq 0) { + $SAM_CMD = "sam" + Write-Success "SAM CLIが見つかりました: sam ($samVersion)" + } else { + Write-Info "samは存在しますが実行できません" + } + } catch { + Write-Info "samの実行中にエラーが発生しました: $_" + } + } else { + Write-Info "samが見つかりません" + } + } + + if (-not $SAM_CMD) { + throw "SAM CLIが見つかりません" + + } +} catch { + Write-Warning "SAM CLIがインストールされていません" + $response = Read-Host "SAM CLIをインストールしますか? (y/N)" + if ($response -eq "y" -or $response -eq "Y") { + Write-Info "SAM CLIのインストール中..." + + # Windows用のインストール方法 + Write-Info "Windows環境でSAM CLIをインストール中..." + + $INSTALL_SUCCESS = $false + + # 方法1: wingetを使用 + if (Get-Command winget -ErrorAction SilentlyContinue) { + Write-Info "wingetを使用してインストールを試行中..." + try { + $result = winget install Amazon.AWSSAMCLI --accept-source-agreements --accept-package-agreements 2>&1 + if ($LASTEXITCODE -eq 0) { + $INSTALL_SUCCESS = $true + Write-Success "wingetでSAM CLIのインストールに成功しました" + } else { + Write-Warning "wingetでのインストールに失敗しました: $result" + } + } catch { + Write-Warning "wingetでのインストール中にエラーが発生しました: $_" + } + } else { + Write-Info "wingetが見つかりません" + } + + + + # 方法3: Scoopを使用 + if (-not $INSTALL_SUCCESS -and (Get-Command scoop -ErrorAction SilentlyContinue)) { + Write-Info "Scoopを使用してインストールを試行中..." + try { + $result = scoop install aws-sam-cli 2>&1 + if ($LASTEXITCODE -eq 0) { + $INSTALL_SUCCESS = $true + Write-Success "ScoopでSAM CLIのインストールに成功しました" + } else { + Write-Warning "Scoopでのインストールに失敗しました: $result" + } + } catch { + Write-Warning "Scoopでのインストール中にエラーが発生しました: $_" + } + } else { + Write-Info "Scoopが見つかりません" + } + + # 方法4: 直接ダウンロード + if (-not $INSTALL_SUCCESS) { + Write-Info "直接ダウンロードでインストールを試行中..." + try { + # 最新バージョンを取得 + $latestVersion = Invoke-RestMethod -Uri "https://api.github.com/repos/aws/aws-sam-cli/releases/latest" | Select-Object -ExpandProperty tag_name + $version = $latestVersion.TrimStart('v') + + # ダウンロードURL + $downloadUrl = "https://github.com/aws/aws-sam-cli/releases/download/$latestVersion/AWS_SAM_CLI_64_PY3.msi" + $installerPath = "$env:TEMP\AWS_SAM_CLI_64_PY3.msi" + + Write-Info "SAM CLI v$version をダウンロード中..." + Invoke-WebRequest -Uri $downloadUrl -OutFile $installerPath + + Write-Info "インストーラーを実行中..." + Start-Process -FilePath "msiexec.exe" -ArgumentList "/i `"$installerPath`" /quiet" -Wait + + # インストール確認 + Start-Sleep -Seconds 3 + if (Get-Command sam -ErrorAction SilentlyContinue) { + $INSTALL_SUCCESS = $true + Write-Success "直接ダウンロードでSAM CLIのインストールに成功しました" + } else { + Write-Warning "直接ダウンロードでのインストールに失敗しました" + } + + # 一時ファイルを削除 + if (Test-Path $installerPath) { + Remove-Item $installerPath -Force -ErrorAction SilentlyContinue + } + } catch { + Write-Warning "直接ダウンロードでのインストール中にエラーが発生しました: $_" + } + } + + if (-not $INSTALL_SUCCESS) { + Write-Error "すべてのインストール方法が失敗しました" + Write-Info "手動でSAM CLIをインストールしてください: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" + exit 1 + } + + # インストール確認 + Write-Info "インストール確認中..." + Start-Sleep -Seconds 3 + + # PATHを再読み込み + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH","User") + + # Windows環境でのSAM CLI確認 + Write-Info "インストール後のSAM CLI確認中..." + $samFound = $false + + # sam.exeを確認 + Write-Info "sam.exeの確認中..." + if (Get-Command sam.exe -ErrorAction SilentlyContinue) { + try { + $version = sam.exe --version 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "SAM CLIがインストールされました: sam.exe ($version)" + $samFound = $true + } else { + Write-Info "sam.exeは存在しますが実行できません" + } + } catch { + Write-Info "sam.exeの実行中にエラーが発生しました: $_" + } + } else { + Write-Info "sam.exeが見つかりません" + } + + # sam.cmdを確認 + if (-not $samFound) { + Write-Info "sam.cmdの確認中..." + if (Get-Command sam.cmd -ErrorAction SilentlyContinue) { + try { + $version = sam.cmd --version 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "SAM CLIがインストールされました: sam.cmd ($version)" + $samFound = $true + } else { + Write-Info "sam.cmdは存在しますが実行できません" + } + } catch { + Write-Info "sam.cmdの実行中にエラーが発生しました: $_" + } + } else { + Write-Info "sam.cmdが見つかりません" + } + } + + # 通常のsamコマンドを確認 + if (-not $samFound) { + Write-Info "samの確認中..." + if (Get-Command sam -ErrorAction SilentlyContinue) { + try { + $version = sam --version 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "SAM CLIがインストールされました: sam ($version)" + $samFound = $true + } else { + Write-Info "samは存在しますが実行できません" + } + } catch { + Write-Info "samの実行中にエラーが発生しました: $_" + } + } else { + Write-Info "samが見つかりません" + } + } + + if (-not $samFound) { + Write-Error "SAM CLIのインストール確認に失敗しました" + Write-Info "手動でインストールしてください: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" + exit 1 + } + } else { + Write-Error "SAM CLIのインストールをスキップしました。手動でインストールしてください" + exit 1 + } +} + +# 3. GitHub CLIの確認 +Write-Info "GitHub CLIの確認中..." +$GITHUB_CLI_FOUND = $false + +# 複数の方法でGitHub CLIを検索 +try { + $ghVersion = gh --version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIがインストールされています: $ghVersion" + $GITHUB_CLI_FOUND = $true + } +} catch { + # エラーが発生した場合は無視して続行 +} + +# Windows環境での追加検索 +if (-not $GITHUB_CLI_FOUND) { + # Windows Git Bashでの検索 + $ghPaths = @( + "C:\Program Files\GitHub CLI\gh.exe", + "$env:USERPROFILE\AppData\Local\Microsoft\WinGet\Packages\GitHub.cli_Microsoft.Winget.Source_8wekyb3d8bbwe\LocalState\links\gh.exe", + "$env:USERPROFILE\AppData\Local\GitHubCLI\gh.exe", + "$env:USERPROFILE\scoop\apps\gh\current\gh.exe" + ) + + foreach ($path in $ghPaths) { + if (Test-Path $path) { + try { + $ghVersion = & $path --version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIがインストールされています: $ghVersion" + Write-Info "パス: $path" + $GITHUB_CLI_FOUND = $true + # PATHに追加 + $env:PATH = "$(Split-Path $path);$env:PATH" + break + } + } catch { + # エラーが発生した場合は無視して続行 + } + } + } + + # wingetでインストールされた場合の確認 + if (-not $GITHUB_CLI_FOUND -and (Get-Command winget -ErrorAction SilentlyContinue)) { + try { + $wingetGh = winget list GitHub.cli 2>$null | Select-String -Pattern "GitHub.cli" + if ($wingetGh) { + Write-Info "wingetでGitHub CLIがインストールされていることを確認しました" + # パスを再検索 + foreach ($path in $ghPaths) { + if (Test-Path $path) { + try { + $ghVersion = & $path --version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIがインストールされています: $ghVersion" + Write-Info "パス: $path" + $GITHUB_CLI_FOUND = $true + $env:PATH = "$(Split-Path $path);$env:PATH" + break + } + } catch { + # エラーが発生した場合は無視して続行 + } + } + } + } + } catch { + # エラーが発生した場合は無視して続行 + } + } + + # Scoopでインストールされた場合の確認 + if (-not $GITHUB_CLI_FOUND -and (Get-Command scoop -ErrorAction SilentlyContinue)) { + try { + $scoopGh = scoop list 2>$null | Select-String -Pattern "gh" + if ($scoopGh) { + Write-Info "scoopでGitHub CLIがインストールされていることを確認しました" + $scoopPath = "$env:USERPROFILE\scoop\apps\gh\current\gh.exe" + if (Test-Path $scoopPath) { + try { + $ghVersion = & $scoopPath --version 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIがインストールされています: $ghVersion" + Write-Info "パス: $scoopPath" + $GITHUB_CLI_FOUND = $true + $env:PATH = "$(Split-Path $scoopPath);$env:PATH" + } + } catch { + # エラーが発生した場合は無視して続行 + } + } + } + } catch { + # エラーが発生した場合は無視して続行 + } + } +} + +if (-not $GITHUB_CLI_FOUND) { + Write-Warning "GitHub CLIがインストールされていません" + $response = Read-Host "GitHub CLIをインストールしますか? (y/N)" + if ($response -eq "y" -or $response -eq "Y") { + $GITHUB_CLI_AVAILABLE = $false + Write-Info "GitHub CLIのインストール中..." + + # Windows用のインストール方法 + Write-Info "Windows環境でGitHub CLIをインストール中..." + + $INSTALL_SUCCESS = $false + + # 方法1: wingetを使用 + if (Get-Command winget -ErrorAction SilentlyContinue) { + Write-Info "wingetを使用してインストールを試行中..." + try { + $result = winget install GitHub.cli --accept-source-agreements --accept-package-agreements 2>&1 + if ($LASTEXITCODE -eq 0) { + $INSTALL_SUCCESS = $true + Write-Success "wingetでGitHub CLIのインストールに成功しました" + } else { + Write-Warning "wingetでのインストールに失敗しました: $result" + } + } catch { + Write-Warning "wingetでのインストール中にエラーが発生しました: $_" + } + } else { + Write-Info "wingetが見つかりません" + } + + + + # 方法3: Scoopを使用 + if (-not $INSTALL_SUCCESS -and (Get-Command scoop -ErrorAction SilentlyContinue)) { + Write-Info "Scoopを使用してインストールを試行中..." + try { + $result = scoop install gh 2>&1 + if ($LASTEXITCODE -eq 0) { + $INSTALL_SUCCESS = $true + Write-Success "ScoopでGitHub CLIのインストールに成功しました" + } else { + Write-Warning "Scoopでのインストールに失敗しました: $result" + } + } catch { + Write-Warning "Scoopでのインストール中にエラーが発生しました: $_" + } + } else { + Write-Info "Scoopが見つからないか、既にインストール済みです" + } + + # 方法4: 直接ダウンロード + if (-not $INSTALL_SUCCESS) { + Write-Info "直接ダウンロードでインストールを試行中..." + try { + # アーキテクチャ判定 + $ARCH = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } + Write-Info "アーキテクチャ: $ARCH" + + # 最新バージョンの取得 + $LATEST_VERSION = (Invoke-RestMethod -Uri "https://api.github.com/repos/cli/cli/releases/latest" -UseBasicParsing).tag_name + $LATEST_VERSION = $LATEST_VERSION.TrimStart('v') + Write-Info "最新バージョン: $LATEST_VERSION" + + $DOWNLOAD_URL = "https://github.com/cli/cli/releases/download/v${LATEST_VERSION}/gh_${LATEST_VERSION}_windows_${ARCH}.zip" + $TEMP_DIR = "$env:TEMP\gh-install" + $ZIP_FILE = "$TEMP_DIR\gh.zip" + $INSTALL_DIR = "$env:ProgramFiles\GitHub CLI" + + Write-Info "ダウンロードURL: $DOWNLOAD_URL" + + # 一時ディレクトリを作成 + if (Test-Path $TEMP_DIR) { + Remove-Item $TEMP_DIR -Recurse -Force -ErrorAction SilentlyContinue + } + New-Item -ItemType Directory -Path $TEMP_DIR -Force | Out-Null + + # インストールディレクトリを作成 + if (-not (Test-Path $INSTALL_DIR)) { + New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null + } + + # ダウンロード + Write-Info "ファイルをダウンロード中..." + Invoke-WebRequest -Uri $DOWNLOAD_URL -OutFile $ZIP_FILE -UseBasicParsing + + # 解凍 + Write-Info "ファイルを解凍中..." + Expand-Archive -Path $ZIP_FILE -DestinationPath $TEMP_DIR -Force + + # インストール + Write-Info "ファイルをインストール中..." + $GH_BIN = Get-ChildItem -Path $TEMP_DIR -Recurse -Name "gh.exe" | Select-Object -First 1 + if ($GH_BIN) { + $GH_PATH = Join-Path $TEMP_DIR $GH_BIN + $TARGET_PATH = Join-Path $INSTALL_DIR "gh.exe" + + Copy-Item -Path $GH_PATH -Destination $TARGET_PATH -Force + Write-Info "GitHub CLIを $TARGET_PATH にコピーしました" + + # PATHに追加 + $CURRENT_PATH = [Environment]::GetEnvironmentVariable("PATH", "Machine") + if ($CURRENT_PATH -notlike "*$INSTALL_DIR*") { + $NEW_PATH = "$CURRENT_PATH;$INSTALL_DIR" + [Environment]::SetEnvironmentVariable("PATH", $NEW_PATH, "Machine") + $env:PATH = "$env:PATH;$INSTALL_DIR" + Write-Info "PATH環境変数を更新しました" + } + + $INSTALL_SUCCESS = $true + Write-Success "直接ダウンロードでGitHub CLIのインストールに成功しました" + } else { + Write-Error "gh.exeが見つかりませんでした" + } + + # クリーンアップ + if (Test-Path $TEMP_DIR) { + Remove-Item $TEMP_DIR -Recurse -Force -ErrorAction SilentlyContinue + } + + } catch { + Write-Warning "直接ダウンロードでのインストールに失敗しました: $_" + } + } + + # インストール確認 + if ($INSTALL_SUCCESS) { + Write-Info "インストール確認中..." + Start-Sleep -Seconds 3 + + # PATHを再読み込み + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH","User") + + if (Get-Command gh -ErrorAction SilentlyContinue) { + $version = gh --version 2>&1 + Write-Success "GitHub CLIがインストールされました: $version" + $GITHUB_CLI_AVAILABLE = $true + } else { + Write-Error "GitHub CLIのインストール確認に失敗しました" + Write-Info "手動でインストールしてください: https://cli.github.com/" + $GITHUB_CLI_AVAILABLE = $false + } + } else { + Write-Error "すべてのインストール方法が失敗しました" + Write-Info "手動でGitHub CLIをインストールしてください: https://cli.github.com/" + $GITHUB_CLI_AVAILABLE = $false + } + } else { + Write-Warning "GitHub CLIのインストールをスキップしました。手動でGitHub Secretsを設定してください" + $GITHUB_CLI_AVAILABLE = $false + } +} + +# GitHub CLIの利用可能性を最終確認 +if ($GITHUB_CLI_FOUND) { + $GITHUB_CLI_AVAILABLE = $true + Write-Info "GitHub CLIが利用可能です" +} + +# 4. 現在のGitブランチの確認 +Write-Info "現在のGitブランチの確認中..." +$CURRENT_BRANCH = git branch --show-current 2>$null +if (-not $CURRENT_BRANCH) { + $CURRENT_BRANCH = git rev-parse --abbrev-ref HEAD 2>$null +} + +if (-not $CURRENT_BRANCH) { + Write-Warning "Gitブランチを取得できませんでした。手動でブランチを選択してください" + Write-Host "" + Write-Host "=== ブランチの選択 ===" -ForegroundColor Cyan + Write-Host "1. main (本番環境用)" + Write-Host "2. deploy (開発環境用)" + Write-Host "3. その他" + Write-Host "" + + do { + $branchChoice = Read-Host "ブランチを選択してください (1-3)" + } while ($branchChoice -notmatch '^[1-3]$') + + switch ($branchChoice) { + "1" { + $CURRENT_BRANCH = "main" + Write-Info "本番環境用の設定を行います" + } + "2" { + $CURRENT_BRANCH = "deploy" + Write-Info "開発環境用の設定を行います" + } + "3" { + $CURRENT_BRANCH = Read-Host "ブランチ名を入力してください" + Write-Info "カスタムブランチ '$CURRENT_BRANCH' の設定を行います" + } + } +} else { + Write-Success "現在のブランチ: $CURRENT_BRANCH" + + if ($CURRENT_BRANCH -eq "main") { + Write-Info "本番環境用の設定を行います" + } elseif ($CURRENT_BRANCH -eq "deploy") { + Write-Info "開発環境用の設定を行います" + } else { + Write-Info "カスタムブランチ '$CURRENT_BRANCH' の設定を行います" + } +} + +# 環境設定の決定 +Write-Info "ブランチ '$CURRENT_BRANCH' に基づいて環境を設定中..." + +if ($CURRENT_BRANCH -eq "main") { + $ENVIRONMENT = "production" + $STACK_NAME = "lambda-framework-prod" + $SECRET_NAME = "AWS_ROLE_ARN_PROD" + Write-Info "mainブランチ → production環境 (本番環境)" +} elseif ($CURRENT_BRANCH -eq "deploy") { + $ENVIRONMENT = "development" + $STACK_NAME = "lambda-framework-dev" + $SECRET_NAME = "AWS_ROLE_ARN_DEV" + Write-Info "deployブランチ → development環境 (開発環境)" +} else { + $ENVIRONMENT = "development" + $STACK_NAME = "lambda-framework-dev" + $SECRET_NAME = "AWS_ROLE_ARN_DEV" + Write-Info "カスタムブランチ '$CURRENT_BRANCH' → development環境 (開発環境)" +} + +Write-Info "環境: $ENVIRONMENT" +Write-Info "スタック名: $STACK_NAME" +Write-Info "GitHub Secret名: $SECRET_NAME" + +# 5. AWS認証情報の確認 +Write-Info "AWS認証情報の確認中..." +try { + $callerIdentity = aws sts get-caller-identity 2>$null | ConvertFrom-Json + if ($LASTEXITCODE -eq 0) { + Write-Success "AWS認証情報が設定されています" + $CURRENT_ACCOUNT = $callerIdentity.Account + Write-Host "Account: $CURRENT_ACCOUNT" + Write-Host "User ID: $($callerIdentity.UserId)" + Write-Host "ARN: $($callerIdentity.Arn)" + + # AWSアカウントの選択 + Write-Host "" + Write-Host "=== AWSアカウントの選択 ===" -ForegroundColor Cyan + Write-Host "1. 現在のアカウントを使用 ($CURRENT_ACCOUNT)" + Write-Host "2. 別のAWSアカウントを設定" + Write-Host "" + + do { + $accountChoice = Read-Host "AWSアカウントを選択してください (1-2)" + } while ($accountChoice -notmatch '^[1-2]$') + + if ($accountChoice -eq "2") { + Write-Info "別のAWSアカウントを設定します" + Write-Host "" + Write-Host "=== AWS認証方法の選択 ===" -ForegroundColor Cyan + Write-Host "1. AWS CLI configure (アクセスキー/シークレットキー)" + Write-Host "2. AWS SSO (Single Sign-On)" + Write-Host "3. AWS IAM Identity Center (旧AWS SSO)" + Write-Host "4. AWS Profile (既存のプロファイル)" + Write-Host "" + + do { + $authChoice = Read-Host "認証方法を選択してください (1-4)" + } while ($authChoice -notmatch '^[1-4]$') + + switch ($authChoice) { + "1" { + Write-Info "AWS CLI configureを実行します" + Write-Host "アクセスキーID、シークレットアクセスキー、リージョンを入力してください" + aws configure + } + "2" { + Write-Info "AWS SSOを設定します" + $ssoStartUrl = Read-Host "SSO Start URLを入力してください (例: https://your-sso-portal.awsapps.com/start)" + $ssoRegion = Read-Host "SSO Regionを入力してください (例: us-east-1)" + $accountId = Read-Host "AWS Account IDを入力してください" + $roleName = Read-Host "SSO Role Nameを入力してください" + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url $ssoStartUrl --sso-region $ssoRegion --account-id $accountId --role-name $roleName + } + "3" { + Write-Info "AWS IAM Identity Centerを設定します" + $ssoStartUrl = Read-Host "Identity Center Start URLを入力してください (例: https://your-portal.awsapps.com/start)" + $ssoRegion = Read-Host "Identity Center Regionを入力してください (例: us-east-1)" + $accountId = Read-Host "AWS Account IDを入力してください" + $roleName = Read-Host "Role Nameを入力してください" + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url $ssoStartUrl --sso-region $ssoRegion --account-id $accountId --role-name $roleName + } + "4" { + Write-Info "既存のAWS Profileを選択します" + $profiles = aws configure list-profiles 2>$null + if ($profiles) { + Write-Host "利用可能なプロファイル:" + $profileArray = $profiles -split "`n" + for ($i = 0; $i -lt $profileArray.Count; $i++) { + Write-Host "$($i+1). $($profileArray[$i])" + } + Write-Host "" + $profileChoice = Read-Host "プロファイル番号を選択してください (1-$($profileArray.Count))" + if ($profileChoice -match '^\d+$' -and [int]$profileChoice -ge 1 -and [int]$profileChoice -le $profileArray.Count) { + $selectedProfile = $profileArray[[int]$profileChoice - 1] + $env:AWS_PROFILE = $selectedProfile + Write-Success "プロファイル '$selectedProfile' が選択されました" + } else { + Write-Error "無効な選択です。デフォルトプロファイルを使用します" + } + } else { + Write-Warning "利用可能なプロファイルが見つかりません。AWS CLI configureを実行します" + aws configure + } + } + } + + # 認証情報の再確認 + Write-Info "認証情報の確認中..." + try { + $newCallerIdentity = aws sts get-caller-identity 2>$null | ConvertFrom-Json + if ($LASTEXITCODE -eq 0) { + Write-Success "AWS認証情報が正常に設定されました" + Write-Host "Account: $($newCallerIdentity.Account)" + Write-Host "User ID: $($newCallerIdentity.UserId)" + Write-Host "ARN: $($newCallerIdentity.Arn)" + $callerIdentity = $newCallerIdentity + } else { + throw "AWS認証情報の設定に失敗しました" + } + } catch { + Write-Error "AWS認証情報の設定に失敗しました" + exit 1 + } + } else { + Write-Info "現在のAWSアカウントを使用します" + } + } else { + throw "AWS認証情報が設定されていません" + } +} catch { + Write-Warning "AWS認証情報が設定されていません。AWS認証方法を選択してください" + Write-Host "" + Write-Host "=== AWS認証方法の選択 ===" -ForegroundColor Cyan + Write-Host "1. AWS CLI configure (アクセスキー/シークレットキー)" + Write-Host "2. AWS SSO (Single Sign-On)" + Write-Host "3. AWS IAM Identity Center (旧AWS SSO)" + Write-Host "4. AWS Profile (既存のプロファイル)" + Write-Host "" + + do { + $authChoice = Read-Host "認証方法を選択してください (1-4)" + } while ($authChoice -notmatch '^[1-4]$') + + switch ($authChoice) { + "1" { + Write-Info "AWS CLI configureを実行します" + Write-Host "アクセスキーID、シークレットアクセスキー、リージョンを入力してください" + aws configure + } + "2" { + Write-Info "AWS SSOを設定します" + $ssoStartUrl = Read-Host "SSO Start URLを入力してください (例: https://your-sso-portal.awsapps.com/start)" + $ssoRegion = Read-Host "SSO Regionを入力してください (例: us-east-1)" + $accountId = Read-Host "AWS Account IDを入力してください" + $roleName = Read-Host "SSO Role Nameを入力してください" + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url $ssoStartUrl --sso-region $ssoRegion --account-id $accountId --role-name $roleName + } + "3" { + Write-Info "AWS IAM Identity Centerを設定します" + $ssoStartUrl = Read-Host "Identity Center Start URLを入力してください (例: https://your-portal.awsapps.com/start)" + $ssoRegion = Read-Host "Identity Center Regionを入力してください (例: us-east-1)" + $accountId = Read-Host "AWS Account IDを入力してください" + $roleName = Read-Host "Role Nameを入力してください" + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url $ssoStartUrl --sso-region $ssoRegion --account-id $accountId --role-name $roleName + } + "4" { + Write-Info "既存のAWS Profileを選択します" + $profiles = aws configure list-profiles 2>$null + if ($profiles) { + Write-Host "利用可能なプロファイル:" + $profileArray = $profiles -split "`n" + for ($i = 0; $i -lt $profileArray.Count; $i++) { + Write-Host "$($i+1). $($profileArray[$i])" + } + Write-Host "" + $profileChoice = Read-Host "プロファイル番号を選択してください (1-$($profileArray.Count))" + if ($profileChoice -match '^\d+$' -and [int]$profileChoice -ge 1 -and [int]$profileChoice -le $profileArray.Count) { + $selectedProfile = $profileArray[[int]$profileChoice - 1] + $env:AWS_PROFILE = $selectedProfile + Write-Success "プロファイル '$selectedProfile' が選択されました" + } else { + Write-Error "無効な選択です。デフォルトプロファイルを使用します" + } + } else { + Write-Warning "利用可能なプロファイルが見つかりません。AWS CLI configureを実行します" + aws configure + } + } + } + + # 認証情報の再確認 + Write-Info "認証情報の確認中..." + $callerIdentity = aws sts get-caller-identity 2>$null | ConvertFrom-Json + if ($LASTEXITCODE -eq 0) { + Write-Success "AWS認証情報が正常に設定されました" + Write-Host "Account: $($callerIdentity.Account)" + Write-Host "User ID: $($callerIdentity.UserId)" + Write-Host "ARN: $($callerIdentity.Arn)" + } else { + Write-Error "AWS認証情報の設定に失敗しました" + exit 1 + } +} + +# 5. GitHubユーザー情報の取得 +Write-Info "GitHubユーザー情報の取得中..." + +# GitHub CLIの利用可能性を再確認 +$GITHUB_CLI_WORKING = $false +$GITHUB_USERNAME = $null +$GITHUB_REPO_NAME = $null + +if ($GITHUB_CLI_AVAILABLE) { + Write-Info "GitHub CLIの認証状態を確認中..." + + # GitHub CLIの認証状態を確認 + try { + $ghStatus = gh auth status 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIにログイン済みです" + $GITHUB_CLI_WORKING = $true + } else { + Write-Warning "GitHub CLIにログインしていません" + Write-Host "" + Write-Host "=== GitHub CLIログイン ===" -ForegroundColor Cyan + Write-Host "GitHub CLIにログインする必要があります" + Write-Host "1. ブラウザでログイン" + Write-Host "2. トークンでログイン" + Write-Host "3. 手動でユーザー情報を入力" + Write-Host "" + + do { + $loginChoice = Read-Host "ログイン方法を選択してください (1-3)" + } while ($loginChoice -notmatch '^[1-3]$') + + switch ($loginChoice) { + "1" { + Write-Info "ブラウザでログインを開始します..." + try { + gh auth login --web + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIログインに成功しました" + $GITHUB_CLI_WORKING = $true + } else { + Write-Error "GitHub CLIログインに失敗しました" + } + } catch { + Write-Error "GitHub CLIログインに失敗しました: $_" + } + } + "2" { + Write-Info "トークンでログインします..." + $githubToken = Read-Host "GitHub Personal Access Tokenを入力してください" + try { + $githubToken | gh auth login --with-token + if ($LASTEXITCODE -eq 0) { + Write-Success "GitHub CLIログインに成功しました" + $GITHUB_CLI_WORKING = $true + } else { + Write-Error "GitHub CLIログインに失敗しました" + } + } catch { + Write-Error "GitHub CLIログインに失敗しました: $_" + } + } + "3" { + Write-Info "手動でユーザー情報を入力します" + $GITHUB_CLI_WORKING = $false + } + } + } + } catch { + Write-Error "GitHub CLIの認証状態確認に失敗しました: $_" + $GITHUB_CLI_WORKING = $false + } + + # GitHub CLIが動作する場合、ユーザー情報を取得 + if ($GITHUB_CLI_WORKING) { + Write-Info "GitHubユーザー情報を取得中..." + + # ユーザー情報の取得 + try { + $userResponse = gh api user 2>$null + if ($LASTEXITCODE -eq 0 -and $userResponse) { + $userData = $userResponse | ConvertFrom-Json + if ($userData.login) { + $GITHUB_USERNAME = $userData.login + Write-Success "GitHubユーザー名: $GITHUB_USERNAME" + } else { + Write-Error "GitHubユーザー名の取得に失敗しました" + $GITHUB_CLI_WORKING = $false + } + } else { + Write-Error "GitHub APIからのユーザー情報取得に失敗しました" + $GITHUB_CLI_WORKING = $false + } + } catch { + Write-Error "GitHubユーザー情報の取得に失敗しました: $_" + $GITHUB_CLI_WORKING = $false + } + + # リポジトリ情報の取得 + if ($GITHUB_CLI_WORKING) { + try { + $repoUrl = git remote get-url origin 2>$null + if ($LASTEXITCODE -eq 0 -and $repoUrl) { + $GITHUB_REPO_NAME = $repoUrl -replace '.*[:/]([^/]+/[^/]+)\.git$', '$1' -replace '.*/', '' + Write-Success "GitHubリポジトリ名: $GITHUB_REPO_NAME" + } else { + Write-Warning "リポジトリ情報の取得に失敗しました。手動で入力してください" + $GITHUB_CLI_WORKING = $false + } + } catch { + Write-Warning "リポジトリ情報の取得に失敗しました: $_" + $GITHUB_CLI_WORKING = $false + } + } + } +} + +# GitHub CLIが利用できない場合、手動で入力 +if (-not $GITHUB_CLI_WORKING) { + Write-Warning "GitHub CLIが利用できません。手動でGitHubユーザー名とリポジトリ名を入力してください" + $GITHUB_USERNAME = Read-Host "GitHubユーザー名を入力してください" + $GITHUB_REPO_NAME = Read-Host "GitHubリポジトリ名を入力してください" +} + +# 6. AWSアカウントIDの取得 +Write-Info "AWSアカウントIDの取得中..." +$AWS_ACCOUNT_ID = aws sts get-caller-identity --query Account --output text 2>$null +if (-not $AWS_ACCOUNT_ID -or $AWS_ACCOUNT_ID -eq "None") { + Write-Error "AWSアカウントIDの取得に失敗しました" + Write-Info "AWS認証情報を確認してください" + aws sts get-caller-identity + exit 1 +} +Write-Success "AWSアカウントID: $AWS_ACCOUNT_ID" + +# AWSリージョンの確認 +Write-Info "AWSリージョンの確認" +$AWS_REGION_INPUT = Read-Host "AWSリージョンを入力してください (デフォルト: ap-northeast-1)" +$AWS_REGION = if ($AWS_REGION_INPUT) { $AWS_REGION_INPUT } else { "ap-northeast-1" } +Write-Success "AWSリージョン: $AWS_REGION" + +# プロジェクト名の確認 +Write-Info "プロジェクト名の確認" +$PROJECT_NAME_INPUT = Read-Host "プロジェクト名を入力してください (デフォルト: LambdaFramework)" +$PROJECT_NAME = if ($PROJECT_NAME_INPUT) { $PROJECT_NAME_INPUT } else { "LambdaFramework" } +Write-Success "プロジェクト名: $PROJECT_NAME" + +# S3バケット名の確認 +Write-Info "S3バケット名の確認" +$S3_BUCKET_INPUT = Read-Host "S3バケット名を入力してください (デフォルト: cn-seba-aws-sam-cli-managed-default-samclisourcebucket)" +$S3_BUCKET = if ($S3_BUCKET_INPUT) { $S3_BUCKET_INPUT } else { "cn-seba-aws-sam-cli-managed-default-samclisourcebucket" } +Write-Success "S3バケット名: $S3_BUCKET" + +# 7. OIDCプロバイダーの選択 +Write-Info "OIDCプロバイダーの選択中..." + +# 既存のOIDCプロバイダー一覧を取得 +Write-Info "既存のOIDCプロバイダーを取得中..." +$OIDC_PROVIDERS = aws iam list-open-id-connect-providers --query 'OpenIDConnectProviderList[].Arn' --output text 2>$null + +# GitHub Actions用のOIDCプロバイダーARN +$GITHUB_OIDC_ARN = "arn:aws:iam:$($AWS_ACCOUNT_ID):oidc-provider/token.actions.githubusercontent.com" + +# 選択肢を準備 +Write-Host "" +Write-Host "=== 利用可能なOIDCプロバイダー ===" -ForegroundColor Cyan +Write-Host "0. 新規作成: GitHub Actions用OIDCプロバイダー" +Write-Host " ($GITHUB_OIDC_ARN)" + +# 既存のプロバイダーを表示 +if ($OIDC_PROVIDERS) { + $PROVIDER_ARRAY = $OIDC_PROVIDERS -split "`t" + for ($i = 0; $i -lt $PROVIDER_ARRAY.Count; $i++) { + $PROVIDER_ARN = $PROVIDER_ARRAY[$i] + $PROVIDER_URL = aws iam get-open-id-connect-provider --open-id-connect-provider-arn $PROVIDER_ARN --query 'Url' --output text 2>$null + Write-Host "$($i+1). $PROVIDER_ARN" + Write-Host " URL: $PROVIDER_URL" + } +} else { + Write-Host "既存のOIDCプロバイダーが見つかりません" +} + +Write-Host "" +$OIDC_CHOICE = Read-Host "OIDCプロバイダーを選択してください (0-$($PROVIDER_ARRAY.Count))" + +# 選択に基づいてOIDCプロバイダーARNを設定 +if ($OIDC_CHOICE -eq "0") { + Write-Info "新規OIDCプロバイダーを作成中..." + $OIDC_PROVIDER_ARN = $GITHUB_OIDC_ARN + + # OIDCプロバイダーが既に存在するかチェック + try { + aws iam get-open-id-connect-provider --open-id-connect-provider-arn $OIDC_PROVIDER_ARN 2>$null | Out-Null + if ($LASTEXITCODE -eq 0) { + Write-Success "OIDCプロバイダーは既に存在します" + } else { + throw "OIDCプロバイダーが存在しません" + } + } catch { + aws iam create-open-id-connect-provider ` + --url https://token.actions.githubusercontent.com ` + --client-id-list sts.amazonaws.com ` + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "OIDCプロバイダーが作成されました" + } else { + Write-Error "OIDCプロバイダーの作成に失敗しました" + exit 1 + } + } +} else { + # 既存のプロバイダーを選択 + if ($OIDC_PROVIDERS -and [int]$OIDC_CHOICE -ge 1 -and [int]$OIDC_CHOICE -le $PROVIDER_ARRAY.Count) { + $SELECTED_INDEX = [int]$OIDC_CHOICE - 1 + $OIDC_PROVIDER_ARN = $PROVIDER_ARRAY[$SELECTED_INDEX] + Write-Success "選択されたOIDCプロバイダー: $OIDC_PROVIDER_ARN" + } else { + Write-Error "無効な選択です。デフォルトで新規作成します" + $OIDC_PROVIDER_ARN = $GITHUB_OIDC_ARN + + try { + aws iam get-open-id-connect-provider --open-id-connect-provider-arn $OIDC_PROVIDER_ARN 2>$null | Out-Null + if ($LASTEXITCODE -eq 0) { + Write-Success "OIDCプロバイダーは既に存在します" + } else { + throw "OIDCプロバイダーが存在しません" + } + } catch { + aws iam create-open-id-connect-provider ` + --url https://token.actions.githubusercontent.com ` + --client-id-list sts.amazonaws.com ` + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 2>$null + if ($LASTEXITCODE -eq 0) { + Write-Success "OIDCプロバイダーが作成されました" + } else { + Write-Error "OIDCプロバイダーの作成に失敗しました" + exit 1 + } + } + } +} + +# 8. IAMロールの作成 +Write-Info "IAMロールの作成について確認します" +$DEFAULT_ROLE_NAME = "$PROJECT_NAME-github-actions-role" +$ROLE_NAME_INPUT = Read-Host "IAMロール名を入力してください (デフォルト: $DEFAULT_ROLE_NAME)" +$ROLE_NAME = if ($ROLE_NAME_INPUT) { $ROLE_NAME_INPUT } else { $DEFAULT_ROLE_NAME } +Write-Info "IAMロールの作成中... ($ROLE_NAME)" + +$TRUST_POLICY = @" +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "$OIDC_PROVIDER_ARN" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" + }, + "StringLike": { + "token.actions.githubusercontent.com:sub": [ + "repo:$GITHUB_USERNAME/$GITHUB_REPO_NAME:ref:refs/heads/main", + "repo:$GITHUB_USERNAME/$GITHUB_REPO_NAME:ref:refs/heads/deploy" + ] + } + } + } + ] +} +"@ + +# ロールが存在するかチェック +try { + $result = aws iam get-role --role-name $ROLE_NAME 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "IAMロールは既に存在します: $ROLE_NAME" + } else { + throw "IAMロールが存在しません" + } +} catch { + Write-Info "IAMロールを作成中..." + + # 一時ファイルを作成してポリシードキュメントを保存 + $TEMP_POLICY_FILE = "$env:TEMP\trust-policy.json" + $TRUST_POLICY | Out-File -FilePath $TEMP_POLICY_FILE -Encoding UTF8 + + try { + $result = aws iam create-role --role-name $ROLE_NAME --assume-role-policy-document file://$TEMP_POLICY_FILE 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "IAMロールが作成されました: $ROLE_NAME" + } else { + Write-Error "IAMロールの作成に失敗しました: $result" + exit 1 + } + } finally { + # 一時ファイルを削除 + if (Test-Path $TEMP_POLICY_FILE) { + Remove-Item $TEMP_POLICY_FILE -Force -ErrorAction SilentlyContinue + } + } +} + +# 9. ポリシーの作成とアタッチ +Write-Info "IAMポリシーの作成について確認します" +$DEFAULT_POLICY_NAME = "$PROJECT_NAME-github-actions-policy" +$POLICY_NAME_INPUT = Read-Host "IAMポリシー名を入力してください (デフォルト: $DEFAULT_POLICY_NAME)" +$POLICY_NAME = if ($POLICY_NAME_INPUT) { $POLICY_NAME_INPUT } else { $DEFAULT_POLICY_NAME } +Write-Info "IAMポリシーの作成中... ($POLICY_NAME)" + +$POLICY_DOCUMENT = @" +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "cloudformation:*", + "lambda:*", + "iam:*", + "logs:*" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "s3:GetObject", + "s3:PutObject", + "s3:DeleteObject", + "s3:ListBucket", + "s3:GetBucketLocation", + "s3:GetObjectVersion", + "s3:PutObjectAcl" + ], + "Resource": [ + "arn:aws:s3:::cn-seba-aws-sam-cli-managed-default-samclisourcebucket", + "arn:aws:s3:::cn-seba-aws-sam-cli-managed-default-samclisourcebucket/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "s3:CreateBucket", + "s3:DeleteBucket", + "s3:ListAllMyBuckets" + ], + "Resource": "*" + } + ] +} +"@ + +# ポリシーが存在するかチェック +Write-Info "IAMポリシーの存在を確認中: $POLICY_NAME" +$policyExists = $false + +# より確実な存在確認方法 +$checkResult = aws iam list-policies --scope Local --query "Policies[?PolicyName=='$POLICY_NAME'].Arn" --output text 2>&1 +if ($LASTEXITCODE -eq 0 -and $checkResult -and $checkResult -ne "None") { + Write-Success "IAMポリシーは既に存在します: $POLICY_NAME" + $policyExists = $true +} else { + Write-Info "IAMポリシーが見つかりません。作成を試行します..." +} + +if (-not $policyExists) { + Write-Info "IAMポリシーを作成中..." + + # 一時ファイルを作成してポリシードキュメントを保存 + $TEMP_POLICY_FILE = "$env:TEMP\policy-document.json" + $POLICY_DOCUMENT | Out-File -FilePath $TEMP_POLICY_FILE -Encoding UTF8 + + try { + $result = aws iam create-policy --policy-name $POLICY_NAME --policy-document file://$TEMP_POLICY_FILE 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "IAMポリシーが作成されました: $POLICY_NAME" + } else { + # 作成に失敗した場合、既に存在する可能性があるので再確認 + $recheckResult = aws iam list-policies --scope Local --query "Policies[?PolicyName=='$POLICY_NAME'].Arn" --output text 2>&1 + if ($LASTEXITCODE -eq 0 -and $recheckResult -and $recheckResult -ne "None") { + Write-Success "IAMポリシーは既に存在します: $POLICY_NAME" + } else { + Write-Error "IAMポリシーの作成に失敗しました: $result" + exit 1 + } + } + } finally { + # 一時ファイルを削除 + if (Test-Path $TEMP_POLICY_FILE) { + Remove-Item $TEMP_POLICY_FILE -Force -ErrorAction SilentlyContinue + } + } +} + +# ポリシーをロールにアタッチ +Write-Info "ポリシーをロールにアタッチ中..." +aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn "arn:aws:iam:$AWS_ACCOUNT_ID:policy/$POLICY_NAME" 2>$null +if ($LASTEXITCODE -eq 0) { + Write-Success "ポリシーがロールにアタッチされました" +} else { + Write-Warning "ポリシーのアタッチに失敗しました(既にアタッチされている可能性があります)" +} + +# 10. GitHub Secretsの自動登録 +if ($GITHUB_CLI_AVAILABLE) { + Write-Info "GitHub Secretsの自動登録について確認します" + + # GitHub CLIの認証状況を確認 + Write-Info "GitHub CLIの認証状況を確認中..." + $authStatus = gh auth status 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Warning "GitHub CLIにログインしていません。ログインしてください" + gh auth login + $authStatus = gh auth status 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Error "GitHub CLIの認証に失敗しました" + $GITHUB_CLI_AVAILABLE = $false + } + } + + if ($GITHUB_CLI_AVAILABLE) { + $response = Read-Host "GitHub Secretsを自動登録しますか? (y/N)" + if ($response -eq "y" -or $response -eq "Y") { + Write-Info "GitHub Secretsの自動登録中..." + + # 現在のリポジトリを確認 + Write-Info "現在のリポジトリを確認中..." + $currentRepo = (gh repo view --json nameWithOwner 2>&1 | ConvertFrom-Json).nameWithOwner + if ($LASTEXITCODE -eq 0) { + Write-Success "リポジトリ: $currentRepo" + } else { + Write-Warning "リポジトリの確認に失敗しました: $currentRepo" + } + + # Repository Secretsの登録(機密情報) + Write-Info "=== Repository Secretsの登録 ===" + + # 環境別AWS_ROLE_ARNの登録 + Write-Info "AWSアカウントID: $AWS_ACCOUNT_ID" + Write-Info "IAMロール名: $ROLE_NAME" + + # PowerShellの文字列展開を確実にする + $AWS_ROLE_ARN = "arn:aws:iam::$($AWS_ACCOUNT_ID):role/$($ROLE_NAME)" + Write-Info "生成されるARN: $AWS_ROLE_ARN" + Write-Info "$SECRET_NAMEをRepository Secretsに登録中: $AWS_ROLE_ARN" + $result = gh variable set $SECRET_NAME --body $AWS_ROLE_ARN 2>&1 + $result = gh secret set $SECRET_NAME --body $AWS_ROLE_ARN 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "$SECRET_NAME がRepository Secretsに登録されました" + } else { + Write-Warning "$SECRET_NAME の登録に失敗しました: $result" + } + + # S3_BUCKETの登録 + Write-Info "S3_BUCKETをRepository Secretsに登録中: $S3_BUCKET" + $result = gh secret set S3_BUCKET --body $S3_BUCKET 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "S3_BUCKET がRepository Secretsに登録されました" + } else { + Write-Warning "S3_BUCKET の登録に失敗しました: $result" + } + + # Repository Variablesの登録(非機密情報) + Write-Info "=== Repository Variablesの登録 ===" + + # AWS_REGIONの登録 + Write-Info "AWS_REGIONをRepository Variablesに登録中: $AWS_REGION" + $result = gh variable set AWS_REGION --body $AWS_REGION 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "AWS_REGION がRepository Variablesに登録されました" + } else { + Write-Warning "AWS_REGION の登録に失敗しました: $result" + } + + # PROJECT_NAMEの登録 + Write-Info "PROJECT_NAMEをRepository Variablesに登録中: $PROJECT_NAME" + $result = gh variable set PROJECT_NAME --body $PROJECT_NAME 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "PROJECT_NAME がRepository Variablesに登録されました" + } else { + Write-Warning "PROJECT_NAME の登録に失敗しました: $result" + } + + # 環境別S3バケットの登録 + Write-Info "S3_BUCKET_DEVをRepository Variablesに登録中: $S3_BUCKET" + $result = gh variable set S3_BUCKET_DEV --body $S3_BUCKET 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "S3_BUCKET_DEV がRepository Variablesに登録されました" + } else { + Write-Warning "S3_BUCKET_DEV の登録に失敗しました: $result" + } + + Write-Info "S3_BUCKET_PRODをRepository Variablesに登録中: $S3_BUCKET" + $result = gh variable set S3_BUCKET_PROD --body $S3_BUCKET 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Success "S3_BUCKET_PROD がRepository Variablesに登録されました" + } else { + Write-Warning "S3_BUCKET_PROD の登録に失敗しました: $result" + } + } else { + Write-Info "GitHub Secretsの自動登録をスキップしました" + } + } +} else { + Write-Warning "GitHub CLIが利用できないため、手動でGitHub Secretsを設定してください" +} + +# 11. 結果の表示 +Write-Success "設定が完了しました!" +Write-Host "" +Write-Host "=== 設定情報 ===" -ForegroundColor Cyan +Write-Host "AWSアカウントID: $AWS_ACCOUNT_ID" +Write-Host "GitHubユーザー名: $GITHUB_USERNAME" +Write-Host "GitHubリポジトリ名: $GITHUB_REPO_NAME" +Write-Host "IAMロール名: $ROLE_NAME" +Write-Host "IAMロールARN: arn:aws:iam::$($AWS_ACCOUNT_ID):role/$($ROLE_NAME)" +Write-Host "" + +if ($GITHUB_CLI_AVAILABLE) { + Write-Success "GitHub SecretsとVariablesが自動登録されました" + Write-Host "登録されたRepository Secrets:" -ForegroundColor Yellow + Write-Host "- $SECRET_NAME" + Write-Host "- S3_BUCKET" + Write-Host "登録されたRepository Variables:" -ForegroundColor Yellow + Write-Host "- AWS_REGION" + Write-Host "- PROJECT_NAME" + Write-Host "- S3_BUCKET_DEV" + Write-Host "- S3_BUCKET_PROD" +} else { + Write-Host "手動でGitHubに以下を設定してください:" -ForegroundColor Yellow + Write-Host "" + Write-Host "Repository Secrets:" -ForegroundColor Cyan + Write-Host "Name: $SECRET_NAME" + Write-Host "Value: arn:aws:iam::$($AWS_ACCOUNT_ID):role/$($ROLE_NAME)" + Write-Host "Name: S3_BUCKET" + Write-Host "Value: $S3_BUCKET" + Write-Host "" + Write-Host "Repository Variables:" -ForegroundColor Cyan + Write-Host "Name: AWS_REGION" + Write-Host "Value: $AWS_REGION" + Write-Host "Name: PROJECT_NAME" + Write-Host "Value: $PROJECT_NAME" + Write-Host "Name: S3_BUCKET_DEV" + Write-Host "Value: $S3_BUCKET" + Write-Host "Name: S3_BUCKET_PROD" + Write-Host "Value: $S3_BUCKET" +} \ No newline at end of file diff --git a/create_role.sh b/create_role.sh new file mode 100644 index 0000000..24e14ef --- /dev/null +++ b/create_role.sh @@ -0,0 +1,1278 @@ +#!/bin/bash + +# 色付き出力用の関数 +print_info() { + echo -e "\033[34m[INFO]\033[0m $1" +} + +print_success() { + echo -e "\033[32m[SUCCESS]\033[0m $1" +} + +print_error() { + echo -e "\033[31m[ERROR]\033[0m $1" +} + +print_warning() { + echo -e "\033[33m[WARNING]\033[0m $1" +} + +# 1. AWS CLIの確認 +print_info "AWS CLIの確認中..." +if ! command -v aws &> /dev/null; then + print_error "AWS CLIがインストールされていません" + exit 1 +fi + +print_success "AWS CLIが見つかりました: $(aws --version)" + +# 2. SAM CLIの確認 +print_info "SAM CLIの確認中..." +SAM_CMD="sam" + +# Windows環境でのSAM CLI確認 +if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ "$(uname)" == "MINGW"* ]] || [[ "$(uname)" == "MSYS"* ]]; then + print_info "Windows環境を検出しました: $OSTYPE ($(uname))" + # Windows環境ではsam.cmdを優先して確認 + print_info "sam.cmdの確認中..." + if command -v sam.cmd &> /dev/null; then + # 実際にバージョン確認を試行 + if sam.cmd --version &> /dev/null; then + SAM_CMD="sam.cmd" + print_success "SAM CLIが見つかりました: sam.cmd ($(sam.cmd --version 2>/dev/null | head -n1))" + else + print_info "sam.cmdは存在しますが実行できません" + fi + else + print_info "sam.cmdが見つかりません" + fi + + if [[ -z "$SAM_CMD" ]]; then + print_info "sam.exeの確認中..." + if command -v sam.exe &> /dev/null; then + # 実際にバージョン確認を試行 + if sam.exe --version &> /dev/null; then + SAM_CMD="sam.exe" + print_success "SAM CLIが見つかりました: sam.exe ($(sam.exe --version 2>/dev/null | head -n1))" + else + print_info "sam.exeは存在しますが実行できません" + fi + else + print_info "sam.exeが見つかりません" + fi + fi + + if [[ -z "$SAM_CMD" ]]; then + print_info "samの確認中..." + if command -v sam &> /dev/null; then + # 実際にバージョン確認を試行 + if sam --version &> /dev/null; then + SAM_CMD="sam" + print_success "SAM CLIが見つかりました: sam ($(sam --version 2>/dev/null | head -n1))" + else + print_info "samは存在しますが実行できません" + fi + else + print_info "samが見つかりません" + fi + fi +else + print_info "非Windows環境を検出しました: $OSTYPE" + # 非Windows環境では通常のsamコマンドを確認 + if command -v sam &> /dev/null; then + SAM_CMD="sam" + else + SAM_CMD="" + fi +fi + +if [[ -z "$SAM_CMD" ]]; then + print_warning "SAM CLIがインストールされていません" + read -p "SAM CLIをインストールしますか? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + print_info "SAM CLIのインストール中..." + + # OS判定とインストール + if [[ "$OSTYPE" == "linux-gnu"* ]] || [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then + # Linux または Windows Git Bash + if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then + print_info "Windows Git Bash環境でSAM CLIをインストール中..." + else + print_info "Linux環境でSAM CLIをインストール中..." + fi + + INSTALL_SUCCESS=false + + # 方法1: pipを使用 + if command -v pip3 &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "pip3を使用してインストールを試行中..." + if pip3 install aws-sam-cli >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "pip3でSAM CLIのインストールに成功しました" + fi + fi + + # 方法2: apt-get (Debian/Ubuntu) + if command -v apt-get &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "apt-getを使用してインストールを試行中..." + if wget https://github.com/aws/aws-sam-cli/releases/latest/download/install-sam-cli.sh -O /tmp/install-sam-cli.sh 2>/dev/null; then + if chmod +x /tmp/install-sam-cli.sh 2>/dev/null; then + if sudo /tmp/install-sam-cli.sh >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "apt-getでSAM CLIのインストールに成功しました" + fi + fi + rm -f /tmp/install-sam-cli.sh + fi + fi + + # 方法3: yum (RHEL/CentOS) + if command -v yum &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "yumを使用してインストールを試行中..." + if wget https://github.com/aws/aws-sam-cli/releases/latest/download/install-sam-cli.sh -O /tmp/install-sam-cli.sh 2>/dev/null; then + if chmod +x /tmp/install-sam-cli.sh 2>/dev/null; then + if sudo /tmp/install-sam-cli.sh >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "yumでSAM CLIのインストールに成功しました" + fi + fi + rm -f /tmp/install-sam-cli.sh + fi + fi + + # 方法4: pip (Windows Git Bash用) + if command -v pip3 &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "pip3を使用してインストールを試行中..." + if pip3 install aws-sam-cli >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "pip3でSAM CLIのインストールに成功しました" + fi + fi + + # 方法5: 直接ダウンロード + if ! $INSTALL_SUCCESS; then + print_info "直接ダウンロードでインストールを試行中..." + ARCH=$(uname -m) + if [[ "$ARCH" == "x86_64" ]]; then + ARCH="x86_64" + elif [[ "$ARCH" == "aarch64" ]]; then + ARCH="arm64" + fi + + # 最新バージョンを取得 + LATEST_VERSION=$(curl -s https://api.github.com/repos/aws/aws-sam-cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + VERSION=${LATEST_VERSION#v} + + if curl -L "https://github.com/aws/aws-sam-cli/releases/download/$LATEST_VERSION/aws-sam-cli-linux-$ARCH.zip" -o /tmp/sam-cli.zip 2>/dev/null; then + if unzip -q /tmp/sam-cli.zip -d /tmp 2>/dev/null; then + # Windows Git Bashの場合はsudoを使わずにコピー + if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then + if cp /tmp/sam-installation/sam /usr/local/bin/ 2>/dev/null || cp /tmp/sam-installation/sam ~/.local/bin/ 2>/dev/null; then + INSTALL_SUCCESS=true + print_success "直接ダウンロードでSAM CLIのインストールに成功しました" + fi + else + if sudo cp /tmp/sam-installation/sam /usr/local/bin/ 2>/dev/null; then + INSTALL_SUCCESS=true + print_success "直接ダウンロードでSAM CLIのインストールに成功しました" + fi + fi + fi + rm -f /tmp/sam-cli.zip + rm -rf /tmp/sam-installation + fi + fi + + elif [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + print_info "macOS環境でSAM CLIをインストール中..." + + INSTALL_SUCCESS=false + + # 方法1: Homebrew + if command -v brew &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "Homebrewを使用してインストールを試行中..." + if brew install aws-sam-cli >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "HomebrewでSAM CLIのインストールに成功しました" + fi + fi + + # 方法2: pip + if command -v pip3 &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "pip3を使用してインストールを試行中..." + if pip3 install aws-sam-cli >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "pip3でSAM CLIのインストールに成功しました" + fi + fi + + # 方法3: 直接ダウンロード + if ! $INSTALL_SUCCESS; then + print_info "直接ダウンロードでインストールを試行中..." + ARCH=$(uname -m) + if [[ "$ARCH" == "x86_64" ]]; then + ARCH="x86_64" + elif [[ "$ARCH" == "arm64" ]]; then + ARCH="arm64" + fi + + # 最新バージョンを取得 + LATEST_VERSION=$(curl -s https://api.github.com/repos/aws/aws-sam-cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + VERSION=${LATEST_VERSION#v} + + if curl -L "https://github.com/aws/aws-sam-cli/releases/download/$LATEST_VERSION/aws-sam-cli-mac-$ARCH.zip" -o /tmp/sam-cli.zip 2>/dev/null; then + if unzip -q /tmp/sam-cli.zip -d /tmp 2>/dev/null; then + if sudo cp /tmp/sam-installation/sam /usr/local/bin/ 2>/dev/null; then + INSTALL_SUCCESS=true + print_success "直接ダウンロードでSAM CLIのインストールに成功しました" + fi + fi + rm -f /tmp/sam-cli.zip + rm -rf /tmp/sam-installation + fi + fi + + else + print_error "サポートされていないOSです。手動でSAM CLIをインストールしてください" + print_info "インストール方法: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" + exit 1 + fi + + if ! $INSTALL_SUCCESS; then + print_error "すべてのインストール方法が失敗しました" + print_info "手動でSAM CLIをインストールしてください: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" + exit 1 + fi + + # インストール確認 + print_info "インストール確認中..." + sleep 3 + + # Windows環境でのSAM CLI確認 + if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ "$(uname)" == "MINGW"* ]] || [[ "$(uname)" == "MSYS"* ]]; then + if command -v sam.exe &> /dev/null; then + print_success "SAM CLIがインストールされました: $(sam.exe --version)" + elif command -v sam.cmd &> /dev/null; then + print_success "SAM CLIがインストールされました: $(sam.cmd --version)" + elif command -v sam &> /dev/null; then + print_success "SAM CLIがインストールされました: $(sam --version)" + else + print_error "SAM CLIのインストール確認に失敗しました" + print_info "手動でインストールしてください: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" + exit 1 + fi + else + if command -v sam &> /dev/null; then + print_success "SAM CLIがインストールされました: $(sam --version)" + else + print_error "SAM CLIのインストール確認に失敗しました" + print_info "手動でインストールしてください: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html" + exit 1 + fi + fi + else + print_error "SAM CLIのインストールをスキップしました。手動でインストールしてください" + exit 1 + fi +else + # Windows環境でのSAM CLI確認 + if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ "$(uname)" == "MINGW"* ]] || [[ "$(uname)" == "MSYS"* ]]; then + if command -v sam.exe &> /dev/null; then + print_success "SAM CLIが見つかりました: $(sam.exe --version)" + elif command -v sam.cmd &> /dev/null; then + print_success "SAM CLIが見つかりました: $(sam.cmd --version)" + elif command -v sam &> /dev/null; then + print_success "SAM CLIが見つかりました: $(sam --version)" + fi + else + print_success "SAM CLIが見つかりました: $(sam --version)" + fi +fi + +# 3. GitHub CLIの確認 +print_info "GitHub CLIの確認中..." +GITHUB_CLI_FOUND=false + +# 複数の方法でGitHub CLIを検索 +if command -v gh &> /dev/null; then + GH_VERSION=$(gh --version 2>/dev/null | head -n1) + if [ $? -eq 0 ]; then + print_success "GitHub CLIがインストールされています: $GH_VERSION" + GITHUB_CLI_FOUND=true + fi +fi + +# Windows環境での追加検索 +if [ "$GITHUB_CLI_FOUND" = false ] && [[ "$OSTYPE" == "msys"* || "$OSTYPE" == "cygwin"* || "$OSTYPE" == "MINGW"* || "$OSTYPE" == "MSYS"* ]]; then + # Windows Git Bashでの検索 + if [ -f "/c/Program Files/GitHub CLI/gh.exe" ]; then + GH_VERSION=$("/c/Program Files/GitHub CLI/gh.exe" --version 2>/dev/null | head -n1) + if [ $? -eq 0 ]; then + print_success "GitHub CLIがインストールされています: $GH_VERSION" + GITHUB_CLI_FOUND=true + # PATHに追加 + export PATH="/c/Program Files/GitHub CLI:$PATH" + fi + fi + + # wingetでインストールされた場合 + if [ "$GITHUB_CLI_FOUND" = false ] && command -v winget &> /dev/null; then + WINGET_GH=$(winget list GitHub.cli 2>/dev/null | grep -i "github.cli") + if [ -n "$WINGET_GH" ]; then + print_info "wingetでGitHub CLIがインストールされていることを確認しました" + # パスを再検索 + for path in "/c/Users/$USER/AppData/Local/Microsoft/WinGet/Packages/GitHub.cli_Microsoft.Winget.Source_8wekyb3d8bbwe/LocalState/links" \ + "/c/Program Files/GitHub CLI" \ + "/c/Users/$USER/AppData/Local/GitHubCLI"; do + if [ -f "$path/gh.exe" ]; then + GH_VERSION=$("$path/gh.exe" --version 2>/dev/null | head -n1) + if [ $? -eq 0 ]; then + print_success "GitHub CLIがインストールされています: $GH_VERSION" + GITHUB_CLI_FOUND=true + export PATH="$path:$PATH" + break + fi + fi + done + fi + fi + + # Scoopでインストールされた場合 + if [ "$GITHUB_CLI_FOUND" = false ] && command -v scoop &> /dev/null; then + SCOOP_GH=$(scoop list 2>/dev/null | grep -i "gh") + if [ -n "$SCOOP_GH" ]; then + print_info "scoopでGitHub CLIがインストールされていることを確認しました" + if [ -f "/c/Users/$USER/scoop/apps/gh/current/gh.exe" ]; then + GH_VERSION=$("/c/Users/$USER/scoop/apps/gh/current/gh.exe" --version 2>/dev/null | head -n1) + if [ $? -eq 0 ]; then + print_success "GitHub CLIがインストールされています: $GH_VERSION" + GITHUB_CLI_FOUND=true + export PATH="/c/Users/$USER/scoop/apps/gh/current:$PATH" + fi + fi + fi + fi +fi + +if [ "$GITHUB_CLI_FOUND" = false ]; then + print_warning "GitHub CLIがインストールされていません" + read -p "GitHub CLIをインストールしますか? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + GITHUB_CLI_AVAILABLE=false + print_info "GitHub CLIのインストール中..." + + # OS判定とインストール + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + # Linux + print_info "Linux環境でGitHub CLIをインストール中..." + + # 複数のインストール方法を試行 + INSTALL_SUCCESS=false + + # 方法1: apt-get (Debian/Ubuntu) + if command -v apt-get &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "apt-getを使用してインストールを試行中..." + if curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null; then + if echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null; then + if sudo apt-get update >/dev/null 2>&1 && sudo apt-get install gh -y >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "apt-getでGitHub CLIのインストールに成功しました" + fi + fi + fi + fi + + # 方法2: yum (RHEL/CentOS) + if command -v yum &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "yumを使用してインストールを試行中..." + if sudo yum install gh -y >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "yumでGitHub CLIのインストールに成功しました" + fi + fi + + # 方法3: dnf (Fedora) + if command -v dnf &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "dnfを使用してインストールを試行中..." + if sudo dnf install gh -y >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "dnfでGitHub CLIのインストールに成功しました" + fi + fi + + # 方法4: 直接ダウンロード + if ! $INSTALL_SUCCESS; then + print_info "直接ダウンロードでインストールを試行中..." + ARCH=$(uname -m) + if [[ "$ARCH" == "x86_64" ]]; then + ARCH="amd64" + elif [[ "$ARCH" == "aarch64" ]]; then + ARCH="arm64" + fi + + if curl -L "https://github.com/cli/cli/releases/latest/download/gh_linux_${ARCH}.tar.gz" -o /tmp/gh.tar.gz 2>/dev/null; then + if tar -xzf /tmp/gh.tar.gz -C /tmp 2>/dev/null; then + if sudo cp /tmp/gh_*/bin/gh /usr/local/bin/ 2>/dev/null; then + INSTALL_SUCCESS=true + print_success "直接ダウンロードでGitHub CLIのインストールに成功しました" + fi + fi + rm -f /tmp/gh.tar.gz + rm -rf /tmp/gh_* + fi + fi + + if ! $INSTALL_SUCCESS; then + print_error "すべてのインストール方法が失敗しました" + print_info "手動でGitHub CLIをインストールしてください: https://cli.github.com/" + GITHUB_CLI_AVAILABLE=false + fi + + elif [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + print_info "macOS環境でGitHub CLIをインストール中..." + + INSTALL_SUCCESS=false + + # 方法1: Homebrew + if command -v brew &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "Homebrewを使用してインストールを試行中..." + if brew install gh >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "HomebrewでGitHub CLIのインストールに成功しました" + fi + fi + + # 方法2: 直接ダウンロード + if ! $INSTALL_SUCCESS; then + print_info "直接ダウンロードでインストールを試行中..." + ARCH=$(uname -m) + if [[ "$ARCH" == "x86_64" ]]; then + ARCH="amd64" + elif [[ "$ARCH" == "arm64" ]]; then + ARCH="arm64" + fi + + if curl -L "https://github.com/cli/cli/releases/latest/download/gh_macOS_${ARCH}.tar.gz" -o /tmp/gh.tar.gz 2>/dev/null; then + if tar -xzf /tmp/gh.tar.gz -C /tmp 2>/dev/null; then + if sudo cp /tmp/gh_*/bin/gh /usr/local/bin/ 2>/dev/null; then + INSTALL_SUCCESS=true + print_success "直接ダウンロードでGitHub CLIのインストールに成功しました" + fi + fi + rm -f /tmp/gh.tar.gz + rm -rf /tmp/gh_* + fi + fi + + if ! $INSTALL_SUCCESS; then + print_error "すべてのインストール方法が失敗しました" + print_info "手動でGitHub CLIをインストールしてください: https://cli.github.com/" + GITHUB_CLI_AVAILABLE=false + fi + + elif [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ "$(uname)" == "MINGW"* ]] || [[ "$(uname)" == "MSYS"* ]]; then + # Windows Git Bash / MSYS2 / Cygwin + print_info "Windows環境でGitHub CLIをインストール中..." + + INSTALL_SUCCESS=false + + # 方法1: winget (Windows Package Manager) + if command -v winget &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "wingetを使用してインストールを試行中..." + if winget install GitHub.cli >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "wingetでGitHub CLIのインストールに成功しました" + fi + fi + + # 方法2: Scoop + if command -v scoop &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "Scoopを使用してインストールを試行中..." + if scoop install gh >/dev/null 2>&1; then + INSTALL_SUCCESS=true + print_success "ScoopでGitHub CLIのインストールに成功しました" + fi + fi + + # 方法3: pip3 (Python経由) + if command -v pip3 &> /dev/null && ! $INSTALL_SUCCESS; then + print_info "pip3を使用してインストールを試行中..." + if pip3 install gh 2>/dev/null; then + INSTALL_SUCCESS=true + print_success "pip3でGitHub CLIのインストールに成功しました" + fi + fi + + # 方法4: 直接ダウンロード + if ! $INSTALL_SUCCESS; then + print_info "直接ダウンロードでインストールを試行中..." + ARCH=$(uname -m) + if [[ "$ARCH" == "x86_64" ]]; then + ARCH="amd64" + elif [[ "$ARCH" == "aarch64" ]]; then + ARCH="arm64" + fi + + # Windows用のダウンロードURL + if curl -L "https://github.com/cli/cli/releases/latest/download/gh_windows_${ARCH}.zip" -o /tmp/gh.zip 2>/dev/null; then + if unzip -q /tmp/gh.zip -d /tmp 2>/dev/null; then + # 実行可能ファイルをPATHに追加 + if [[ -d "$HOME/bin" ]]; then + cp /tmp/gh_*/bin/gh.exe "$HOME/bin/" 2>/dev/null + export PATH="$HOME/bin:$PATH" + elif [[ -d "/usr/local/bin" ]]; then + cp /tmp/gh_*/bin/gh.exe /usr/local/bin/ 2>/dev/null + else + # カレントディレクトリにコピー + cp /tmp/gh_*/bin/gh.exe ./ 2>/dev/null + export PATH="$(pwd):$PATH" + fi + INSTALL_SUCCESS=true + print_success "直接ダウンロードでGitHub CLIのインストールに成功しました" + fi + rm -f /tmp/gh.zip + rm -rf /tmp/gh_* + fi + fi + + if ! $INSTALL_SUCCESS; then + print_error "すべてのインストール方法が失敗しました" + print_info "手動でGitHub CLIをインストールしてください: https://cli.github.com/" + print_info "Windows環境では以下を試してください:" + print_info "1. winget install GitHub.cli" + print_info "2. scoop install gh" + print_info "3. https://cli.github.com/ から直接ダウンロード" + GITHUB_CLI_AVAILABLE=false + fi + + else + print_error "サポートされていないOSです。手動でGitHub CLIをインストールしてください" + print_info "インストール方法: https://cli.github.com/" + GITHUB_CLI_AVAILABLE=false + fi + + # インストール確認 + if command -v gh &> /dev/null; then + print_success "GitHub CLIがインストールされました: $(gh --version)" + GITHUB_CLI_AVAILABLE=true + else + print_error "GitHub CLIのインストールに失敗しました" + GITHUB_CLI_AVAILABLE=false + fi + else + print_warning "GitHub CLIのインストールをスキップしました。手動でGitHub Secretsを設定してください" + GITHUB_CLI_AVAILABLE=false + fi +else + print_success "GitHub CLIが見つかりました: $(gh --version)" + GITHUB_CLI_AVAILABLE=true +fi + +# GitHub CLIの利用可能性を最終確認 +if [ "$GITHUB_CLI_FOUND" = true ]; then + GITHUB_CLI_AVAILABLE=true + print_info "GitHub CLIが利用可能です" +fi + +# 4. 現在のGitブランチの確認 +print_info "現在のGitブランチの確認中..." +CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || git rev-parse --abbrev-ref HEAD 2>/dev/null) + +if [[ -z "$CURRENT_BRANCH" ]]; then + print_warning "Gitブランチを取得できませんでした。手動でブランチを選択してください" + echo "" + echo "=== ブランチの選択 ===" + echo "1. main (本番環境用)" + echo "2. deploy (開発環境用)" + echo "3. その他" + echo "" + + while true; do + read -p "ブランチを選択してください (1-3): " branch_choice + if [[ "$branch_choice" =~ ^[1-3]$ ]]; then + break + fi + echo "無効な選択です。1-3の数字を入力してください。" + done + + case $branch_choice in + 1) + CURRENT_BRANCH="main" + print_info "本番環境用の設定を行います" + ;; + 2) + CURRENT_BRANCH="deploy" + print_info "開発環境用の設定を行います" + ;; + 3) + read -p "ブランチ名を入力してください: " CURRENT_BRANCH + print_info "カスタムブランチ '$CURRENT_BRANCH' の設定を行います" + ;; + esac +else + print_success "現在のブランチ: $CURRENT_BRANCH" + + if [[ "$CURRENT_BRANCH" == "main" ]]; then + print_info "本番環境用の設定を行います" + elif [[ "$CURRENT_BRANCH" == "deploy" ]]; then + print_info "開発環境用の設定を行います" + else + print_info "カスタムブランチ '$CURRENT_BRANCH' の設定を行います" + fi +fi + +# 環境設定の決定 +print_info "ブランチ '$CURRENT_BRANCH' に基づいて環境を設定中..." + +if [[ "$CURRENT_BRANCH" == "main" ]]; then + ENVIRONMENT="production" + STACK_NAME="lambda-framework-prod" + SECRET_NAME="AWS_ROLE_ARN_PROD" + print_info "mainブランチ → production環境 (本番環境)" +elif [[ "$CURRENT_BRANCH" == "deploy" ]]; then + ENVIRONMENT="development" + STACK_NAME="lambda-framework-dev" + SECRET_NAME="AWS_ROLE_ARN_DEV" + print_info "deployブランチ → development環境 (開発環境)" +else + ENVIRONMENT="development" + STACK_NAME="lambda-framework-dev" + SECRET_NAME="AWS_ROLE_ARN_DEV" + print_info "カスタムブランチ '$CURRENT_BRANCH' → development環境 (開発環境)" +fi + +print_info "環境: $ENVIRONMENT" +print_info "スタック名: $STACK_NAME" +print_info "GitHub Secret名: $SECRET_NAME" + +# 5. AWS認証情報の確認 +print_info "AWS認証情報の確認中..." +if aws sts get-caller-identity &> /dev/null; then + print_success "AWS認証情報が設定されています" + CALLER_IDENTITY=$(aws sts get-caller-identity) + CURRENT_ACCOUNT=$(echo "$CALLER_IDENTITY" | grep -o '"Account": "[^"]*"' | sed 's/"Account": "//;s/"//') + echo "Account: $CURRENT_ACCOUNT" + echo "User ID: $(echo "$CALLER_IDENTITY" | grep -o '"UserId": "[^"]*"' | sed 's/"UserId": "//;s/"//')" + echo "ARN: $(echo "$CALLER_IDENTITY" | grep -o '"Arn": "[^"]*"' | sed 's/"Arn": "//;s/"//')" + + # AWSアカウントの選択 + echo "" + echo "=== AWSアカウントの選択 ===" + echo "1. 現在のアカウントを使用 ($CURRENT_ACCOUNT)" + echo "2. 別のAWSアカウントを設定" + echo "" + + while true; do + read -p "AWSアカウントを選択してください (1-2): " account_choice + if [[ "$account_choice" =~ ^[1-2]$ ]]; then + break + fi + echo "無効な選択です。1-2の数字を入力してください。" + done + + if [[ "$account_choice" == "2" ]]; then + print_info "別のAWSアカウントを設定します" + echo "" + echo "=== AWS認証方法の選択 ===" + echo "1. AWS CLI configure (アクセスキー/シークレットキー)" + echo "2. AWS SSO (Single Sign-On)" + echo "3. AWS IAM Identity Center (旧AWS SSO)" + echo "4. AWS Profile (既存のプロファイル)" + echo "" + + while true; do + read -p "認証方法を選択してください (1-4): " auth_choice + if [[ "$auth_choice" =~ ^[1-4]$ ]]; then + break + fi + echo "無効な選択です。1-4の数字を入力してください。" + done + + case $auth_choice in + 1) + print_info "AWS CLI configureを実行します" + echo "アクセスキーID、シークレットアクセスキー、リージョンを入力してください" + aws configure + ;; + 2) + print_info "AWS SSOを設定します" + read -p "SSO Start URLを入力してください (例: https://your-sso-portal.awsapps.com/start): " sso_start_url + read -p "SSO Regionを入力してください (例: us-east-1): " sso_region + read -p "AWS Account IDを入力してください: " account_id + read -p "SSO Role Nameを入力してください: " role_name + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url "$sso_start_url" --sso-region "$sso_region" --account-id "$account_id" --role-name "$role_name" + ;; + 3) + print_info "AWS IAM Identity Centerを設定します" + read -p "Identity Center Start URLを入力してください (例: https://your-portal.awsapps.com/start): " sso_start_url + read -p "Identity Center Regionを入力してください (例: us-east-1): " sso_region + read -p "AWS Account IDを入力してください: " account_id + read -p "Role Nameを入力してください: " role_name + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url "$sso_start_url" --sso-region "$sso_region" --account-id "$account_id" --role-name "$role_name" + ;; + 4) + print_info "既存のAWS Profileを選択します" + profiles=$(aws configure list-profiles 2>/dev/null) + if [ -n "$profiles" ]; then + echo "利用可能なプロファイル:" + profile_array=($profiles) + for i in "${!profile_array[@]}"; do + echo "$((i+1)). ${profile_array[$i]}" + done + echo "" + read -p "プロファイル番号を選択してください (1-${#profile_array[@]}): " profile_choice + if [[ "$profile_choice" =~ ^[0-9]+$ ]] && [ "$profile_choice" -ge 1 ] && [ "$profile_choice" -le "${#profile_array[@]}" ]; then + selected_profile="${profile_array[$((profile_choice-1))]}" + export AWS_PROFILE="$selected_profile" + print_success "プロファイル '$selected_profile' が選択されました" + else + print_error "無効な選択です。デフォルトプロファイルを使用します" + fi + else + print_warning "利用可能なプロファイルが見つかりません。AWS CLI configureを実行します" + aws configure + fi + ;; + esac + + # 認証情報の再確認 + print_info "認証情報の確認中..." + if aws sts get-caller-identity &> /dev/null; then + print_success "AWS認証情報が正常に設定されました" + CALLER_IDENTITY=$(aws sts get-caller-identity) + echo "Account: $(echo "$CALLER_IDENTITY" | grep -o '"Account": "[^"]*"' | sed 's/"Account": "//;s/"//')" + echo "User ID: $(echo "$CALLER_IDENTITY" | grep -o '"UserId": "[^"]*"' | sed 's/"UserId": "//;s/"//')" + echo "ARN: $(echo "$CALLER_IDENTITY" | grep -o '"Arn": "[^"]*"' | sed 's/"Arn": "//;s/"//')" + else + print_error "AWS認証情報の設定に失敗しました" + exit 1 + fi + else + print_info "現在のAWSアカウントを使用します" + fi +else + print_warning "AWS認証情報が設定されていません。AWS認証方法を選択してください" + echo "" + echo "=== AWS認証方法の選択 ===" + echo "1. AWS CLI configure (アクセスキー/シークレットキー)" + echo "2. AWS SSO (Single Sign-On)" + echo "3. AWS IAM Identity Center (旧AWS SSO)" + echo "4. AWS Profile (既存のプロファイル)" + echo "" + + while true; do + read -p "認証方法を選択してください (1-4): " auth_choice + if [[ "$auth_choice" =~ ^[1-4]$ ]]; then + break + fi + echo "無効な選択です。1-4の数字を入力してください。" + done + + case $auth_choice in + 1) + print_info "AWS CLI configureを実行します" + echo "アクセスキーID、シークレットアクセスキー、リージョンを入力してください" + aws configure + ;; + 2) + print_info "AWS SSOを設定します" + read -p "SSO Start URLを入力してください (例: https://your-sso-portal.awsapps.com/start): " sso_start_url + read -p "SSO Regionを入力してください (例: us-east-1): " sso_region + read -p "AWS Account IDを入力してください: " account_id + read -p "SSO Role Nameを入力してください: " role_name + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url "$sso_start_url" --sso-region "$sso_region" --account-id "$account_id" --role-name "$role_name" + ;; + 3) + print_info "AWS IAM Identity Centerを設定します" + read -p "Identity Center Start URLを入力してください (例: https://your-portal.awsapps.com/start): " sso_start_url + read -p "Identity Center Regionを入力してください (例: us-east-1): " sso_region + read -p "AWS Account IDを入力してください: " account_id + read -p "Role Nameを入力してください: " role_name + + aws configure sso-session --profile default + aws configure sso --profile default --sso-start-url "$sso_start_url" --sso-region "$sso_region" --account-id "$account_id" --role-name "$role_name" + ;; + 4) + print_info "既存のAWS Profileを選択します" + profiles=$(aws configure list-profiles 2>/dev/null) + if [ -n "$profiles" ]; then + echo "利用可能なプロファイル:" + profile_array=($profiles) + for i in "${!profile_array[@]}"; do + echo "$((i+1)). ${profile_array[$i]}" + done + echo "" + read -p "プロファイル番号を選択してください (1-${#profile_array[@]}): " profile_choice + if [[ "$profile_choice" =~ ^[0-9]+$ ]] && [ "$profile_choice" -ge 1 ] && [ "$profile_choice" -le "${#profile_array[@]}" ]; then + selected_profile="${profile_array[$((profile_choice-1))]}" + export AWS_PROFILE="$selected_profile" + print_success "プロファイル '$selected_profile' が選択されました" + else + print_error "無効な選択です。デフォルトプロファイルを使用します" + fi + else + print_warning "利用可能なプロファイルが見つかりません。AWS CLI configureを実行します" + aws configure + fi + ;; + esac + + # 認証情報の再確認 + print_info "認証情報の確認中..." + if aws sts get-caller-identity &> /dev/null; then + print_success "AWS認証情報が正常に設定されました" + CALLER_IDENTITY=$(aws sts get-caller-identity) + echo "Account: $(echo "$CALLER_IDENTITY" | grep -o '"Account": "[^"]*"' | sed 's/"Account": "//;s/"//')" + echo "User ID: $(echo "$CALLER_IDENTITY" | grep -o '"UserId": "[^"]*"' | sed 's/"UserId": "//;s/"//')" + echo "ARN: $(echo "$CALLER_IDENTITY" | grep -o '"Arn": "[^"]*"' | sed 's/"Arn": "//;s/"//')" + else + print_error "AWS認証情報の設定に失敗しました" + exit 1 + fi +fi + +# 5. GitHubユーザー情報の取得 +print_info "GitHubユーザー情報の取得中..." + +# GitHub CLIの利用可能性を再確認 +GITHUB_CLI_WORKING=false +if [ "$GITHUB_CLI_AVAILABLE" = true ]; then + print_info "GitHub CLIの認証状態を確認中..." + + # GitHub CLIの認証状態を確認 + if gh auth status &> /dev/null; then + print_success "GitHub CLIにログイン済みです" + GITHUB_CLI_WORKING=true + else + print_warning "GitHub CLIにログインしていません" + echo "" + echo "=== GitHub CLIログイン ===" + echo "GitHub CLIにログインする必要があります" + echo "1. ブラウザでログイン" + echo "2. トークンでログイン" + echo "3. 手動でユーザー情報を入力" + echo "" + + while true; do + read -p "ログイン方法を選択してください (1-3): " login_choice + if [[ "$login_choice" =~ ^[1-3]$ ]]; then + break + fi + echo "無効な選択です。1-3の数字を入力してください。" + done + + case $login_choice in + 1) + print_info "ブラウザでログインを開始します..." + if gh auth login --web; then + print_success "GitHub CLIログインに成功しました" + GITHUB_CLI_WORKING=true + else + print_error "GitHub CLIログインに失敗しました" + fi + ;; + 2) + print_info "トークンでログインします..." + read -p "GitHub Personal Access Tokenを入力してください: " github_token + if gh auth login --with-token <<< "$github_token"; then + print_success "GitHub CLIログインに成功しました" + GITHUB_CLI_WORKING=true + else + print_error "GitHub CLIログインに失敗しました" + fi + ;; + 3) + print_info "手動でユーザー情報を入力します" + GITHUB_CLI_WORKING=false + ;; + esac + fi + + # GitHub CLIが動作する場合、ユーザー情報を取得 + if [ "$GITHUB_CLI_WORKING" = true ]; then + print_info "GitHubユーザー情報を取得中..." + + # ユーザー情報の取得 + USER_RESPONSE=$(gh api user 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$USER_RESPONSE" ]; then + GITHUB_USERNAME=$(echo "$USER_RESPONSE" | grep -o '"login": "[^"]*"' | sed 's/"login": "//;s/"//') + if [ -n "$GITHUB_USERNAME" ]; then + print_success "GitHubユーザー名: $GITHUB_USERNAME" + else + print_error "GitHubユーザー名の取得に失敗しました" + GITHUB_CLI_WORKING=false + fi + else + print_error "GitHub APIからのユーザー情報取得に失敗しました" + GITHUB_CLI_WORKING=false + fi + + # リポジトリ情報の取得 + if [ "$GITHUB_CLI_WORKING" = true ]; then + REPO_RESPONSE=$(gh api repos/$GITHUB_USERNAME/$(basename $(git remote get-url origin 2>/dev/null) .git) 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$REPO_RESPONSE" ]; then + GITHUB_REPO_NAME=$(basename $(git remote get-url origin 2>/dev/null) .git) + print_success "GitHubリポジトリ名: $GITHUB_REPO_NAME" + else + print_warning "リポジトリ情報の取得に失敗しました。手動で入力してください" + GITHUB_CLI_WORKING=false + fi + fi + fi +fi + +# GitHub CLIが利用できない場合、手動で入力 +if [ "$GITHUB_CLI_WORKING" = false ]; then + print_warning "GitHub CLIが利用できません。手動でGitHubユーザー名とリポジトリ名を入力してください" + read -p "GitHubユーザー名を入力してください: " GITHUB_USERNAME + read -p "GitHubリポジトリ名を入力してください: " GITHUB_REPO_NAME +fi + +# 6. AWSアカウントIDの取得 +print_info "AWSアカウントIDの取得中..." +AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) +if [ -z "$AWS_ACCOUNT_ID" ] || [ "$AWS_ACCOUNT_ID" = "None" ]; then + print_error "AWSアカウントIDの取得に失敗しました" + print_info "AWS認証情報を確認してください" + aws sts get-caller-identity + exit 1 +fi +print_success "AWSアカウントID: $AWS_ACCOUNT_ID" + +# AWSリージョンの確認 +print_info "AWSリージョンの確認" +read -p "AWSリージョンを入力してください (デフォルト: ap-northeast-1): " AWS_REGION_INPUT +AWS_REGION=${AWS_REGION_INPUT:-"ap-northeast-1"} +print_success "AWSリージョン: $AWS_REGION" + +# プロジェクト名の確認 +print_info "プロジェクト名の確認" +read -p "プロジェクト名を入力してください (デフォルト: LambdaFramework): " PROJECT_NAME_INPUT +PROJECT_NAME=${PROJECT_NAME_INPUT:-"LambdaFramework"} +print_success "プロジェクト名: $PROJECT_NAME" + +# S3バケット名の確認 +print_info "S3バケット名の確認" +read -p "S3バケット名を入力してください (デフォルト: cn-seba-aws-sam-cli-managed-default-samclisourcebucket): " S3_BUCKET_INPUT +S3_BUCKET=${S3_BUCKET_INPUT:-"cn-seba-aws-sam-cli-managed-default-samclisourcebucket"} +print_success "S3バケット名: $S3_BUCKET" + +# 7. OIDCプロバイダーの選択 +print_info "OIDCプロバイダーの選択中..." + +# 既存のOIDCプロバイダー一覧を取得 +print_info "既存のOIDCプロバイダーを取得中..." +OIDC_PROVIDERS=$(aws iam list-open-id-connect-providers --query 'OpenIDConnectProviderList[].Arn' --output text 2>/dev/null) + +# GitHub Actions用のOIDCプロバイダーARN +GITHUB_OIDC_ARN="arn:aws:iam::$AWS_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com" + +# 選択肢を準備 +echo "" +echo "=== 利用可能なOIDCプロバイダー ===" +echo "0. 新規作成: GitHub Actions用OIDCプロバイダー" +echo " ($GITHUB_OIDC_ARN)" + +# 既存のプロバイダーを表示 +if [ -n "$OIDC_PROVIDERS" ]; then + IFS=$'\t' read -ra PROVIDER_ARRAY <<< "$OIDC_PROVIDERS" + for i in "${!PROVIDER_ARRAY[@]}"; do + PROVIDER_ARN="${PROVIDER_ARRAY[$i]}" + PROVIDER_URL=$(aws iam get-open-id-connect-provider --open-id-connect-provider-arn "$PROVIDER_ARN" --query 'Url' --output text 2>/dev/null) + echo "$((i+1)). $PROVIDER_ARN" + echo " URL: $PROVIDER_URL" + done +else + echo "既存のOIDCプロバイダーが見つかりません" +fi + +echo "" +read -p "OIDCプロバイダーを選択してください (0-${#PROVIDER_ARRAY[@]}): " OIDC_CHOICE + +# 選択に基づいてOIDCプロバイダーARNを設定 +if [ "$OIDC_CHOICE" = "0" ]; then + print_info "新規OIDCプロバイダーを作成中..." + OIDC_PROVIDER_ARN="$GITHUB_OIDC_ARN" + + # OIDCプロバイダーが既に存在するかチェック + if ! aws iam get-open-id-connect-provider --open-id-connect-provider-arn "$OIDC_PROVIDER_ARN" &> /dev/null; then + aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 + print_success "OIDCプロバイダーが作成されました" + else + print_success "OIDCプロバイダーは既に存在します" + fi +else + # 既存のプロバイダーを選択 + if [ -n "$OIDC_PROVIDERS" ] && [ "$OIDC_CHOICE" -ge 1 ] && [ "$OIDC_CHOICE" -le "${#PROVIDER_ARRAY[@]}" ]; then + SELECTED_INDEX=$((OIDC_CHOICE-1)) + OIDC_PROVIDER_ARN="${PROVIDER_ARRAY[$SELECTED_INDEX]}" + print_success "選択されたOIDCプロバイダー: $OIDC_PROVIDER_ARN" + else + print_error "無効な選択です。デフォルトで新規作成します" + OIDC_PROVIDER_ARN="$GITHUB_OIDC_ARN" + + if ! aws iam get-open-id-connect-provider --open-id-connect-provider-arn "$OIDC_PROVIDER_ARN" &> /dev/null; then + aws iam create-open-id-connect-provider \ + --url https://token.actions.githubusercontent.com \ + --client-id-list sts.amazonaws.com \ + --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 + print_success "OIDCプロバイダーが作成されました" + else + print_success "OIDCプロバイダーは既に存在します" + fi + fi +fi + +# 8. IAMロールの作成 +print_info "IAMロールの作成について確認します" +DEFAULT_ROLE_NAME="${PROJECT_NAME}-github-actions-role" +read -p "IAMロール名を入力してください (デフォルト: $DEFAULT_ROLE_NAME): " ROLE_NAME_INPUT +ROLE_NAME=${ROLE_NAME_INPUT:-$DEFAULT_ROLE_NAME} +print_info "IAMロールの作成中... ($ROLE_NAME)" +TRUST_POLICY=$(cat < /dev/null; then + print_info "IAMロールを作成中..." + aws iam create-role \ + --role-name "$ROLE_NAME" \ + --assume-role-policy-document "$TRUST_POLICY" + print_success "IAMロールが作成されました: $ROLE_NAME" +else + print_success "IAMロールは既に存在します: $ROLE_NAME" +fi + +# 9. ポリシーの作成とアタッチ +print_info "IAMポリシーの作成について確認します" +DEFAULT_POLICY_NAME="${PROJECT_NAME}-github-actions-policy" +read -p "IAMポリシー名を入力してください (デフォルト: $DEFAULT_POLICY_NAME): " POLICY_NAME_INPUT +POLICY_NAME=${POLICY_NAME_INPUT:-$DEFAULT_POLICY_NAME} +print_info "IAMポリシーの作成中... ($POLICY_NAME)" +POLICY_DOCUMENT=$(cat </dev/null) +if [ $? -eq 0 ] && [ -n "$CHECK_RESULT" ] && [ "$CHECK_RESULT" != "None" ]; then + print_success "IAMポリシーは既に存在します: $POLICY_NAME" + POLICY_EXISTS=true +else + print_info "IAMポリシーが見つかりません。作成を試行します..." +fi + +if [ "$POLICY_EXISTS" = false ]; then + print_info "IAMポリシーを作成中..." + aws iam create-policy \ + --policy-name "$POLICY_NAME" \ + --policy-document "$POLICY_DOCUMENT" + + if [ $? -eq 0 ]; then + print_success "IAMポリシーが作成されました: $POLICY_NAME" + else + # 作成に失敗した場合、既に存在する可能性があるので再確認 + RECHECK_RESULT=$(aws iam list-policies --scope Local --query "Policies[?PolicyName=='$POLICY_NAME'].Arn" --output text 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$RECHECK_RESULT" ] && [ "$RECHECK_RESULT" != "None" ]; then + print_success "IAMポリシーは既に存在します: $POLICY_NAME" + else + print_error "IAMポリシーの作成に失敗しました" + exit 1 + fi + fi +fi + +# ポリシーをロールにアタッチ +print_info "ポリシーをロールにアタッチ中..." +aws iam attach-role-policy \ + --role-name "$ROLE_NAME" \ + --policy-arn "arn:aws:iam::$AWS_ACCOUNT_ID:policy/$POLICY_NAME" +print_success "ポリシーがロールにアタッチされました" + +# 10. GitHub Secretsの自動登録 +if [ "$GITHUB_CLI_AVAILABLE" = true ]; then + print_info "GitHub Secretsの自動登録について確認します" + read -p "GitHub Secretsを自動登録しますか? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + print_info "GitHub Secretsの自動登録中..." + + # Repository Secretsの登録(機密情報) + print_info "=== Repository Secretsの登録 ===" + + # 環境別AWS_ROLE_ARNの登録 + AWS_ROLE_ARN="arn:aws:iam::$AWS_ACCOUNT_ID:role/$ROLE_NAME" + print_info "登録するARN: $AWS_ROLE_ARN" + if gh secret set "$SECRET_NAME" --body "$AWS_ROLE_ARN" &> /dev/null; then + print_success "$SECRET_NAMEがRepository Secretsに登録されました" + else + print_warning "$SECRET_NAMEの登録に失敗しました" + print_info "手動でGitHub Secretsに設定してください:" + print_info "Name: $SECRET_NAME" + print_info "Value: $AWS_ROLE_ARN" + fi + + # S3_BUCKETの登録 + if gh secret set S3_BUCKET --body "$S3_BUCKET" &> /dev/null; then + print_success "S3_BUCKETがRepository Secretsに登録されました" + else + print_warning "S3_BUCKETの登録に失敗しました" + fi + + # Repository Variablesの登録(非機密情報) + print_info "=== Repository Variablesの登録 ===" + + # AWS_REGIONの登録 + if gh variable set AWS_REGION --body "$AWS_REGION" &> /dev/null; then + print_success "AWS_REGIONがRepository Variablesに登録されました" + else + print_warning "AWS_REGIONの登録に失敗しました" + fi + + # PROJECT_NAMEの登録 + if gh variable set PROJECT_NAME --body "$PROJECT_NAME" &> /dev/null; then + print_success "PROJECT_NAMEがRepository Variablesに登録されました" + else + print_warning "PROJECT_NAMEの登録に失敗しました" + fi + + # 環境別S3バケットの登録 + if gh variable set S3_BUCKET_DEV --body "$S3_BUCKET" &> /dev/null; then + print_success "S3_BUCKET_DEVがRepository Variablesに登録されました" + else + print_warning "S3_BUCKET_DEVの登録に失敗しました" + fi + + if gh variable set S3_BUCKET_PROD --body "$S3_BUCKET" &> /dev/null; then + print_success "S3_BUCKET_PRODがRepository Variablesに登録されました" + else + print_warning "S3_BUCKET_PRODの登録に失敗しました" + fi + else + print_info "GitHub Secretsの自動登録をスキップしました" + fi +else + print_warning "GitHub CLIが利用できないため、手動でGitHub Secretsを設定してください" +fi + +# 11. 結果の表示 +print_success "設定が完了しました!" +echo "" +echo "=== 設定情報 ===" +echo "AWSアカウントID: $AWS_ACCOUNT_ID" +echo "GitHubユーザー名: $GITHUB_USERNAME" +echo "GitHubリポジトリ名: $GITHUB_REPO_NAME" +echo "IAMロール名: $ROLE_NAME" +echo "IAMロールARN: arn:aws:iam::$AWS_ACCOUNT_ID:role/$ROLE_NAME" +echo "" + +if [ "$GITHUB_CLI_AVAILABLE" = true ]; then + print_success "GitHub SecretsとVariablesが自動登録されました" + echo "登録されたRepository Secrets:" + echo "- $SECRET_NAME" + echo "- S3_BUCKET" + echo "登録されたRepository Variables:" + echo "- AWS_REGION" + echo "- PROJECT_NAME" + echo "- S3_BUCKET_DEV" + echo "- S3_BUCKET_PROD" +else + echo "手動でGitHubに以下を設定してください:" + echo "" + echo "Repository Secrets:" + echo "Name: $SECRET_NAME" + echo "Value: arn:aws:iam::$AWS_ACCOUNT_ID:role/$ROLE_NAME" + echo "Name: S3_BUCKET" + echo "Value: $S3_BUCKET" + echo "" + echo "Repository Variables:" + echo "Name: AWS_REGION" + echo "Value: $AWS_REGION" + echo "Name: PROJECT_NAME" + echo "Value: $PROJECT_NAME" + echo "Name: S3_BUCKET_DEV" + echo "Value: $S3_BUCKET" + echo "Name: S3_BUCKET_PROD" + echo "Value: $S3_BUCKET" +fi \ No newline at end of file diff --git a/deploy-env.ps1 b/deploy-env.ps1 new file mode 100644 index 0000000..1ecae91 --- /dev/null +++ b/deploy-env.ps1 @@ -0,0 +1,96 @@ +# 環境別デプロイスクリプト (PowerShell) +# 使用方法: .\deploy-env.ps1 [development|production] [aws-profile] + +param( + [Parameter(Mandatory=$false)] + [ValidateSet("development", "production")] + [string]$Environment = "development", + + [Parameter(Mandatory=$false)] + [string]$AwsProfile = "" +) + +# 色付きメッセージ関数 +function Write-Info { + param([string]$Message) + Write-Host "[INFO] $Message" -ForegroundColor Blue +} + +function Write-Success { + param([string]$Message) + Write-Host "[SUCCESS] $Message" -ForegroundColor Green +} + +function Write-Warning { + param([string]$Message) + Write-Host "[WARNING] $Message" -ForegroundColor Yellow +} + +function Write-Error { + param([string]$Message) + Write-Host "[ERROR] $Message" -ForegroundColor Red +} + +# 環境の確認 +Write-Info "環境: $Environment" +if ($AwsProfile) { + Write-Info "AWS Profile: $AwsProfile" + $env:AWS_PROFILE = $AwsProfile +} + +# スタック名の設定 +if ($Environment -eq "production") { + $StackName = "lambda-framework-prod" + Write-Info "本番環境にデプロイします" +} else { + $StackName = "lambda-framework-dev" + Write-Info "開発環境にデプロイします" +} + +Write-Info "スタック名: $StackName" + +# SAMビルド +Write-Info "SAMビルドを実行中..." +try { + sam build + if ($LASTEXITCODE -eq 0) { + Write-Success "SAMビルドが完了しました" + } else { + throw "SAMビルドに失敗しました" + } +} catch { + Write-Error "SAMビルド中にエラーが発生しました: $_" + exit 1 +} + +# SAMデプロイ +Write-Info "SAMデプロイを実行中..." +try { + if ($AwsProfile) { + sam deploy ` + --config-env $Environment ` + --stack-name $StackName ` + --no-confirm-changeset ` + --no-fail-on-empty-changeset ` + --parameter-overrides "Environment=$Environment" ` + --profile $AwsProfile + } else { + sam deploy ` + --config-env $Environment ` + --stack-name $StackName ` + --no-confirm-changeset ` + --no-fail-on-empty-changeset ` + --parameter-overrides "Environment=$Environment" + } + + if ($LASTEXITCODE -eq 0) { + Write-Success "デプロイが完了しました!" + Write-Info "スタック名: $StackName" + Write-Info "環境: $Environment" + } else { + throw "SAMデプロイに失敗しました" + } +} catch { + Write-Error "SAMデプロイ中にエラーが発生しました: $_" + exit 1 +} \ No newline at end of file diff --git a/deploy-env.sh b/deploy-env.sh new file mode 100644 index 0000000..8e86868 --- /dev/null +++ b/deploy-env.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# 環境別デプロイスクリプト +# 使用方法: ./deploy-env.sh [development|production] [aws-profile] + +set -e + +# 色付きメッセージ関数 +print_info() { + echo -e "\033[34m[INFO]\033[0m $1" +} + +print_success() { + echo -e "\033[32m[SUCCESS]\033[0m $1" +} + +print_warning() { + echo -e "\033[33m[WARNING]\033[0m $1" +} + +print_error() { + echo -e "\033[31m[ERROR]\033[0m $1" +} + +# 環境の確認 +ENVIRONMENT=${1:-development} +AWS_PROFILE=${2:-} + +if [[ "$ENVIRONMENT" != "development" && "$ENVIRONMENT" != "production" ]]; then + print_error "無効な環境です。development または production を指定してください。" + echo "使用方法: $0 [development|production] [aws-profile]" + exit 1 +fi + +print_info "環境: $ENVIRONMENT" +if [[ -n "$AWS_PROFILE" ]]; then + print_info "AWS Profile: $AWS_PROFILE" + export AWS_PROFILE="$AWS_PROFILE" +fi + +# スタック名の設定 +if [[ "$ENVIRONMENT" == "production" ]]; then + STACK_NAME="lambda-framework-prod" + print_info "本番環境にデプロイします" +else + STACK_NAME="lambda-framework-dev" + print_info "開発環境にデプロイします" +fi + +print_info "スタック名: $STACK_NAME" + +# SAMビルド +print_info "SAMビルドを実行中..." +sam build + +# SAMデプロイ +print_info "SAMデプロイを実行中..." +if [[ -n "$AWS_PROFILE" ]]; then + sam deploy \ + --config-env $ENVIRONMENT \ + --stack-name $STACK_NAME \ + --no-confirm-changeset \ + --no-fail-on-empty-changeset \ + --parameter-overrides Environment=$ENVIRONMENT \ + --profile $AWS_PROFILE +else + sam deploy \ + --config-env $ENVIRONMENT \ + --stack-name $STACK_NAME \ + --no-confirm-changeset \ + --no-fail-on-empty-changeset \ + --parameter-overrides Environment=$ENVIRONMENT +fi + +print_success "デプロイが完了しました!" +print_info "スタック名: $STACK_NAME" +print_info "環境: $ENVIRONMENT" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index d72e7b0..3246dcf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ awslambdaric +rpds-py jsonschema jsonpath-ng diff --git a/samconfig.toml b/samconfig.toml new file mode 100644 index 0000000..25d9f75 --- /dev/null +++ b/samconfig.toml @@ -0,0 +1,34 @@ +version = 0.1 + +[default] +[default.deploy] +[default.deploy.parameters] +stack_name = "lambda-framework-prod" +s3_bucket = "cn-seba-aws-sam-cli-managed-default-samclisourcebucket" +region = "ap-northeast-1" +confirm_changeset = false +capabilities = "CAPABILITY_IAM" +parameter_overrides = "ProjectName=LambdaFramework Environment=production" +image_repositories = [] + +[development] +[development.deploy] +[development.deploy.parameters] +stack_name = "lambda-framework-dev" +s3_bucket = "cn-seba-aws-sam-cli-managed-default-samclisourcebucket" +region = "ap-northeast-1" +confirm_changeset = false +capabilities = "CAPABILITY_IAM" +parameter_overrides = "ProjectName=LambdaFramework Environment=development" +image_repositories = [] + +[production] +[production.deploy] +[production.deploy.parameters] +stack_name = "lambda-framework-prod" +s3_bucket = "cn-seba-aws-sam-cli-managed-default-samclisourcebucket" +region = "ap-northeast-1" +confirm_changeset = false +capabilities = "CAPABILITY_IAM" +parameter_overrides = "ProjectName=LambdaFramework Environment=production" +image_repositories = [] \ No newline at end of file diff --git a/template.yaml b/template.yaml index 97d3744..f668837 100644 --- a/template.yaml +++ b/template.yaml @@ -1,18 +1,34 @@ + AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 + +Parameters: + ProjectName: + Type: String + Default: LambdaFramework + Description: Project name for the Lambda layer + Environment: + Type: String + Default: development + AllowedValues: + - development + - production + Description: Environment name + Resources: LambdaFramework: Type: AWS::Serverless::LayerVersion Properties: - LayerName: LambdaFramework - Description: Safe retry and stop framework - ContentUri: lib + LayerName: !Sub "${ProjectName}" + Description: !Sub "Safe retry and stop framework" + ContentUri: LambdaFramework RetentionPolicy: Retain CompatibleRuntimes: - python3.9 - python3.10 + Outputs: - LambdaFramework: - Value: !Ref LambdaFramework - Export: - Name: Layer-LambdaFramework + LambdaFramework: + Value: !Ref LambdaFramework + Export: + Name: !Sub "Layer-${ProjectName}"