-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[review] EventBridge Scheduler のスケジュール登録 #14
Merged
Merged
Changes from 3 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
4a31910
eventbridge scheduler 構築の rake task を追加
kzkn 390c751
refactor: ECSタスクのデータ取得を別クラス化
kzkn f6e4169
refactor: AWSリソース関連の処理を rake タスクの外へ移動
kzkn 2c33557
feat: コンテナスペックの切り替え指定ができるように
interu 14ed8d3
Merge pull request #18 from SonicGarden/interu-2023-10-27
interu 3be74ad
Merge remote-tracking branch 'origin/main' into kzkn-20231013-eventbr…
interu 3379305
feat: run_taskのコンテナスペックを選択制に変更
interu 1494df7
feat: github actionsで自動テスト
interu f8dc710
fix: 最終行
interu fa88775
refactor: review指摘対応
interu 97ea3b7
chore: commit漏れ
interu 22d87a3
Merge pull request #21 from SonicGarden/interu-2023-10-31
interu c1c257c
feat: config/eventbridge_schedules.ymlでRAILS_ENVごとにスケジュールを調整できるように
interu 174d617
feat: EventBridgeScheduleのymlをRAILS_ENVごとに切り替えれるように
interu 7706a3d
Merge pull request #23 from SonicGarden/main
aki77 2d9a9ef
Merge pull request #22 from SonicGarden/interu-2023-10-31
interu bdff0f1
dump: v0.1.9
interu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
require 'net/http' | ||
require 'json' | ||
require 'aws-sdk-ec2' | ||
|
||
module SgFargateRails | ||
class CurrentEcsTask | ||
def cluster_arn | ||
metadata[:Cluster] | ||
end | ||
|
||
def task_definition_arn | ||
"#{cluster_arn.split(":cluster/")[0]}:task-definition/#{metadata[:Family]}:#{metadata[:Revision]}" | ||
end | ||
|
||
def cfn_stack_name | ||
"#{ENV['COPILOT_APPLICATION_NAME']}-#{ENV['COPILOT_ENVIRONMENT_NAME']}" | ||
end | ||
|
||
def security_group_ids | ||
@security_group_ids ||= fetch_security_group_ids | ||
end | ||
|
||
def public_subnet_ids | ||
@public_subnet_ids ||= fetch_public_subnet_ids | ||
end | ||
|
||
private | ||
|
||
def metadata | ||
@metadata ||= begin | ||
response = Net::HTTP.get(URI.parse("#{ENV['ECS_CONTAINER_METADATA_URI']}/task")) | ||
JSON.parse(response, symbolize_names: true) | ||
end | ||
end | ||
|
||
def region | ||
ENV['AWS_REGION'] || 'ap-northeast-1' | ||
end | ||
|
||
def ec2_client | ||
@ec2_client ||= Aws::EC2::Client.new(region: region, credentials: credentials) | ||
end | ||
|
||
def credentials | ||
@credentials ||= Aws::ECSCredentials.new(retries: 3) | ||
end | ||
|
||
def fetch_security_group_ids | ||
security_group_params = { | ||
filters: [ | ||
{ | ||
name: 'tag:aws:cloudformation:logical-id', | ||
values: ['EnvironmentSecurityGroup'], | ||
}, | ||
{ | ||
name: 'tag:aws:cloudformation:stack-name', | ||
values: [cfn_stack_name], | ||
} | ||
], | ||
} | ||
resp = ec2_client.describe_security_groups(security_group_params) | ||
resp.to_h[:security_groups].map { |group| group[:group_id] } | ||
end | ||
|
||
def fetch_public_subnet_ids | ||
subnet_params = { | ||
filters: [ | ||
{ | ||
name: 'tag:aws:cloudformation:logical-id', | ||
values: %w[PublicSubnet1 PublicSubnet2], | ||
}, | ||
{ | ||
name: 'tag:aws:cloudformation:stack-name', | ||
values: [cfn_stack_name], | ||
}, | ||
], | ||
} | ||
resp = ec2_client.describe_subnets(subnet_params) | ||
resp.to_h[:subnets].map { |subnet| subnet[:subnet_id] } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
require "aws-sdk-scheduler" | ||
|
||
module SgFargateRails | ||
class EventBridgeSchedule | ||
attr_reader :name | ||
|
||
def initialize(name, cron, command) | ||
@name = name | ||
@cron = cron | ||
@command = command | ||
end | ||
|
||
def create_run_task(group_name:, cluster_arn:, task_definition_arn:, network_configuration:) | ||
params = { | ||
name: @name, | ||
state: 'ENABLED', | ||
flexible_time_window: { mode: 'OFF' }, | ||
group_name: group_name, | ||
schedule_expression: @cron, | ||
schedule_expression_timezone: timezone, | ||
target: { | ||
arn: cluster_arn, | ||
ecs_parameters: { | ||
task_count: 1, | ||
task_definition_arn: task_definition_arn, | ||
launch_type: 'FARGATE', | ||
network_configuration: network_configuration | ||
}, | ||
input: { | ||
"containerOverrides": [ | ||
{ | ||
"name": "rails", | ||
"command": container_command, | ||
} | ||
] | ||
}.to_json, | ||
retry_policy: { | ||
maximum_event_age_in_seconds: 120, | ||
maximum_retry_attempts: 2, | ||
}, | ||
role_arn: role_arn_for(group_name, cluster_arn), | ||
}, | ||
} | ||
client.create_schedule(params) | ||
end | ||
|
||
def container_command | ||
%w[bundle exec] + @command.split(' ') | ||
end | ||
|
||
private | ||
|
||
def timezone | ||
ENV['TZ'] || 'Asia/Tokyo' | ||
end | ||
|
||
def role_arn_for(group_name, cluster_arn) | ||
account_id = cluster_arn.split(':')[4] | ||
"arn:aws:iam::#{account_id}:role/#{group_name}-eventbridge-scheduler-role" | ||
end | ||
|
||
def client | ||
self.class.client | ||
end | ||
|
||
class << self | ||
def parse(filename) | ||
schedules = YAML.load(File.open(filename)) | ||
schedules.map { |name, info| EventBridgeSchedule.new(name, info['cron'], info['command']) } | ||
end | ||
|
||
def delete_all!(group_name) | ||
client.list_schedules(group_name: group_name, max_results: 100).schedules.each do |schedule| | ||
client.delete_schedule(name: schedule.name, group_name: group_name) | ||
Rails.logger.info "[EventBridgeSchedule] Deleted #{group_name}/#{schedule.name}" | ||
end | ||
end | ||
|
||
def client | ||
@client ||= Aws::Scheduler::Client.new(region: region, credentials: credentials) | ||
end | ||
|
||
def region | ||
ENV['AWS_REGION'] || 'ap-northeast-1' | ||
end | ||
|
||
def credentials | ||
Aws::ECSCredentials.new(retries: 3) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
namespace :sg_fargate_rails do | ||
require 'sg_fargate_rails' | ||
|
||
desc 'EventBridge Schedules' | ||
task recreate_schedules: :environment do | ||
ecs_task = SgFargateRails::CurrentEcsTask.new | ||
Rails.logger.info "[INFO] security_group_ids: #{ecs_task.security_group_ids}" | ||
Rails.logger.info "[INFO] subnet_ids: #{ecs_task.public_subnet_ids}" | ||
|
||
group_name = ecs_task.cfn_stack_name | ||
Rails.logger.info "[EventBridgeSchedule] Clear all schedules in #{group_name}" | ||
SgFargateRails::EventBridgeSchedule.delete_all!(group_name) | ||
|
||
Rails.logger.info "[EventBridgeSchedule] Register schedules in #{group_name}" | ||
config_file = Rails.root.join('config/eventbridge_schedules.yml') | ||
SgFargateRails::EventBridgeSchedule.parse(config_file).each do |schedule| | ||
Rails.logger.info "[EventBridgeSchedule] Register schedule #{schedule.name} in #{group_name}" | ||
# TODO: この辺で AWS の API Limit などのエラーが発生するとスケジュールが消えたままとなるので、エラーの内容に応じてリトライなどのエラー処理が必要 | ||
schedule.create_run_task( | ||
group_name: group_name, | ||
cluster_arn: ecs_task.cluster_arn, | ||
task_definition_arn: ecs_task.task_definition_arn, | ||
network_configuration: { | ||
awsvpc_configuration: { | ||
assign_public_ip: 'ENABLED', | ||
security_groups: ecs_task.security_group_ids, | ||
subnets: ecs_task.public_subnet_ids, | ||
}, | ||
} | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ruby 3.1の記法じゃなかったっけ?3.0とかでもOKだったっけ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここはメソッドのキーワード引数(必須)なので、前から書けるはず。
3.1 からのやつはハッシュリテラルの省略記法ですね。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
なるほど!