AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Parameters: StageName: Type: String Default: Prod Description: Name of the API stage SourceBucketName: Type: String Default: naputo-blog-source Description: S3 bucket for blog source files RepoURL: Type: String Default: "https://git.n-daisuke897.com/nakada0907/n-daisuke897-blog.git" Description: Git repository URL RepoBranch: Type: String Default: main Description: Git repository branch ImageDigest: Type: String Default: "" Description: "ECR image digest (e.g., sha256:abc123...). If empty, uses 'latest' tag. Use digest for deterministic deployments." Conditions: UseDigest: !Not [!Equals [!Ref ImageDigest, ""]] Resources: MyLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: LambdaS3PutObjectPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - s3:PutObject - s3:GetObject - s3:ListBucket Resource: - !Sub "arn:aws:s3:::${SourceBucketName}" - !Sub "arn:aws:s3:::${SourceBucketName}/*" - PolicyName: LambdaEcrImagePullPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ecr:GetAuthorizationToken Resource: "*" - Effect: Allow Action: - ecr:BatchGetImage - ecr:BatchCheckLayerAvailability - ecr:GetDownloadUrlForLayer Resource: Fn::ImportValue: BlogDeployment-RepositoryArn ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole MyLambdaFunction: Type: AWS::Serverless::Function Properties: FunctionName: blog-deployment-webhook-handler PackageType: Image ImageUri: !If - UseDigest - !Sub - "${RepoUri}@${Digest}" - RepoUri: !ImportValue BlogDeployment-RepositoryUri Digest: !Ref ImageDigest - !Sub - "${RepoUri}:latest" - RepoUri: !ImportValue BlogDeployment-RepositoryUri Timeout: 300 MemorySize: 512 Architectures: - arm64 AutoPublishAlias: live Environment: Variables: REPO_URL: !Ref RepoURL REPO_BRANCH: !Ref RepoBranch S3_BUCKET: !Ref SourceBucketName S3_KEY: "source.zip" WEBHOOK_SECRET: Fn::Sub: - "{{resolve:secretsmanager:${SecretArn}:SecretString:secretNumber:AWSCURRENT}}" - SecretArn: Fn::ImportValue: SecretForWebhook-ARN Role: !GetAtt MyLambdaRole.Arn Events: ForgejoWebhook: Type: Api Properties: RestApiId: !Ref MyApi Path: /forgejo-webhook Method: POST MyApi: Type: AWS::Serverless::Api Properties: Name: blog-deployment-webhook-api StageName: !Ref StageName EndpointConfiguration: REGIONAL DefinitionBody: openapi: "3.0.1" info: title: "Forgejo Webhook API" version: "1.0" paths: /forgejo-webhook: post: summary: "Trigger Lambda via Forgejo Webhook" x-amazon-apigateway-integration: uri: Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations httpMethod: POST type: aws_proxy responses: '200': description: "Successful response" '400': description: "Bad Request - Incorrect request payload format" '401': description: "Unauthorized - Signature verification failed" '500': description: "Server error - Deployment process failed" Outputs: ApiEndpoint: Description: API Gateway endpoint URL for webhook Value: !Sub "https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/${StageName}/forgejo-webhook" Export: Name: !Sub "${AWS::StackName}-ApiEndpoint" LambdaFunctionArn: Description: Lambda function ARN Value: !GetAtt MyLambdaFunction.Arn Export: Name: !Sub "${AWS::StackName}-LambdaArn" LambdaFunctionName: Description: Lambda function name Value: !Ref MyLambdaFunction Export: Name: !Sub "${AWS::StackName}-LambdaName"