5f676dfb6b
Dispatcher now launches Spot instances instead of Fargate tasks: - t3.small for go/node builds ($0.005/hr) - t3.medium for docker/godot builds ($0.01/hr) - t3.micro for deploy jobs ($0.004/hr) Instances self-terminate via user-data trap on exit. Cancel: ec2:TerminateInstances instead of ecs:StopTask. Cleanup cron also sweeps orphan instances by tinqs-ci tag. Pre-baked AMI with act_runner + tools = instant boot, no install.
178 lines
4.8 KiB
YAML
178 lines
4.8 KiB
YAML
AWSTemplateFormatVersion: '2010-09-09'
|
|
Transform: AWS::Serverless-2016-10-31
|
|
Description: Tinqs CI Orchestrator — Lambda dispatch + EC2 Spot runners
|
|
|
|
Parameters:
|
|
GiteaURL:
|
|
Type: String
|
|
Default: https://tinqs.com
|
|
GiteaToken:
|
|
Type: String
|
|
NoEcho: true
|
|
RunnerAMI:
|
|
Type: AWS::EC2::Image::Id
|
|
Description: Pre-baked AMI with Go, Node, Docker, AWS CLI, act_runner
|
|
Subnet:
|
|
Type: AWS::EC2::Subnet::Id
|
|
Description: Public subnet for spot instances
|
|
SecurityGroup:
|
|
Type: AWS::EC2::SecurityGroup::Id
|
|
Description: Security group for spot instances
|
|
InstanceProfileArn:
|
|
Type: String
|
|
Description: IAM instance profile ARN for runners
|
|
|
|
Globals:
|
|
Function:
|
|
Runtime: provided.al2023
|
|
Architectures: [x86_64]
|
|
Timeout: 30
|
|
MemorySize: 128
|
|
|
|
Resources:
|
|
|
|
# --- API Gateway ---
|
|
WebhookApi:
|
|
Type: AWS::Serverless::Api
|
|
Properties:
|
|
Name: tinqs-ci-webhook
|
|
StageName: prod
|
|
|
|
# --- DynamoDB ---
|
|
RunsTable:
|
|
Type: AWS::DynamoDB::Table
|
|
Properties:
|
|
TableName: tinqs-ci-runs
|
|
BillingMode: PAY_PER_REQUEST
|
|
AttributeDefinitions:
|
|
- AttributeName: repo
|
|
AttributeType: S
|
|
- AttributeName: run_id
|
|
AttributeType: S
|
|
KeySchema:
|
|
- AttributeName: repo
|
|
KeyType: HASH
|
|
- AttributeName: run_id
|
|
KeyType: RANGE
|
|
TimeToLiveSpecification:
|
|
AttributeName: ttl
|
|
Enabled: true
|
|
|
|
# --- Dispatcher Lambda ---
|
|
DispatchFunction:
|
|
Type: AWS::Serverless::Function
|
|
Properties:
|
|
FunctionName: tinqs-ci-dispatch
|
|
Handler: bootstrap
|
|
CodeUri: ../dispatch/
|
|
Description: Receives webhook, starts Spot instances or invokes Lambda executor
|
|
Timeout: 60
|
|
MemorySize: 256
|
|
Environment:
|
|
Variables:
|
|
GITEA_URL: !Ref GiteaURL
|
|
GITEA_TOKEN: !Ref GiteaToken
|
|
EXECUTOR_FUNCTION_NAME: !Ref ExecFunction
|
|
RUNNER_AMI: !Ref RunnerAMI
|
|
SUBNET: !Ref Subnet
|
|
SECURITY_GROUP: !Ref SecurityGroup
|
|
DDB_TABLE: !Ref RunsTable
|
|
INSTANCE_PROFILE: !Ref InstanceProfileArn
|
|
Policies:
|
|
- LambdaInvokePolicy:
|
|
FunctionName: !Ref ExecFunction
|
|
- DynamoDBCrudPolicy:
|
|
TableName: !Ref RunsTable
|
|
- Version: '2012-10-17'
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- ec2:RunInstances
|
|
- ec2:TerminateInstances
|
|
- ec2:DescribeInstances
|
|
- ec2:CreateTags
|
|
Resource: '*'
|
|
- Effect: Allow
|
|
Action: iam:PassRole
|
|
Resource: !Ref InstanceProfileArn
|
|
Events:
|
|
Webhook:
|
|
Type: Api
|
|
Properties:
|
|
RestApiId: !Ref WebhookApi
|
|
Path: /webhook
|
|
Method: POST
|
|
|
|
# --- Executor Lambda (deploy-only jobs) ---
|
|
ExecFunction:
|
|
Type: AWS::Serverless::Function
|
|
Properties:
|
|
FunctionName: tinqs-ci-exec
|
|
Handler: bootstrap
|
|
CodeUri: ../exec/
|
|
Description: Executes deploy-only workflow steps directly in Lambda
|
|
Timeout: 900
|
|
MemorySize: 2048
|
|
EphemeralStorage:
|
|
Size: 5120
|
|
Environment:
|
|
Variables:
|
|
GITEA_URL: !Ref GiteaURL
|
|
GITEA_TOKEN: !Ref GiteaToken
|
|
Policies:
|
|
- S3CrudPolicy:
|
|
BucketName: tinqs-cli-releases
|
|
- S3CrudPolicy:
|
|
BucketName: arikigame.com
|
|
- S3CrudPolicy:
|
|
BucketName: docs.tinqs.com
|
|
- Version: '2012-10-17'
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- ecs:UpdateService
|
|
- ecs:DescribeServices
|
|
Resource: !Sub 'arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:service/tinqs-git/*'
|
|
- Effect: Allow
|
|
Action:
|
|
- cloudfront:CreateInvalidation
|
|
Resource: '*'
|
|
|
|
# --- Cleanup Cron (every 5 min) ---
|
|
CleanupRule:
|
|
Type: AWS::Events::Rule
|
|
Properties:
|
|
Name: tinqs-ci-cleanup
|
|
ScheduleExpression: 'rate(5 minutes)'
|
|
State: ENABLED
|
|
Targets:
|
|
- Id: cleanup
|
|
Arn: !GetAtt DispatchFunction.Arn
|
|
Input: '{"body":"{\"action\":\"cleanup\"}","headers":{}}'
|
|
|
|
CleanupPermission:
|
|
Type: AWS::Lambda::Permission
|
|
Properties:
|
|
FunctionName: !Ref DispatchFunction
|
|
Action: lambda:InvokeFunction
|
|
Principal: events.amazonaws.com
|
|
SourceArn: !GetAtt CleanupRule.Arn
|
|
|
|
# --- Log Group ---
|
|
CILogGroup:
|
|
Type: AWS::Logs::LogGroup
|
|
Properties:
|
|
LogGroupName: /tinqs/ci
|
|
RetentionInDays: 14
|
|
|
|
Outputs:
|
|
WebhookURL:
|
|
Description: Configure as Gitea system webhook
|
|
Value: !Sub 'https://${WebhookApi}.execute-api.${AWS::Region}.amazonaws.com/prod/webhook'
|
|
DispatchArn:
|
|
Value: !GetAtt DispatchFunction.Arn
|
|
ExecArn:
|
|
Value: !GetAtt ExecFunction.Arn
|
|
RunsTable:
|
|
Value: !Ref RunsTable
|