From d56c66f96d23959ded0aad06474498dc3582fb78 Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Tue, 20 Sep 2022 14:54:49 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20StepFunctions=E3=81=AEGit=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- stepfunctions/TOOLS/convert.conf | 24 +++ stepfunctions/TOOLS/convert_definition.py | 173 ++++++++++++++++++ .../r-crm-datafetch-state.json | 129 +++++++++++++ 4 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 stepfunctions/TOOLS/convert.conf create mode 100644 stepfunctions/TOOLS/convert_definition.py create mode 100644 stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json diff --git a/.gitignore b/.gitignore index 4342f002..dc81048e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,7 @@ node_modules/ # ローカル確認用環境変数ファイル .env # pythonのキャッシュファイル -__pycache__/ \ No newline at end of file +__pycache__/ + +# StepFunctionsステートメント定義変換後のフォルダ +stepfunctions/*/build \ No newline at end of file diff --git a/stepfunctions/TOOLS/convert.conf b/stepfunctions/TOOLS/convert.conf new file mode 100644 index 00000000..3d62ff57 --- /dev/null +++ b/stepfunctions/TOOLS/convert.conf @@ -0,0 +1,24 @@ +# +# 各項目の第1カラムにリプレース前文字列を記載する +# 各項目の第2カラムstagingの情報を記載する +# 各項目の第3カラムにproductの情報を記載する +# 変換前文字列と変換後文字列をカンマで区切る +# + +# AWSアカウントID +{REPLACE_AWS_ACCOUNT_ID},826466435614,826466435614 + +# 環境情報 +{REPLACE_ENV_NAME},staging,product + +# サブネット(PrivateSubnet1) +{REPLACE_SUBNET_PRI_1A},subnet-0a47b12f6899ab19e,subnet-0d9bf8cd421cf2489 + +# サブネット(PrivateSubnet2) +{REPLACE_SUBNET_PRI_1D},subnet-0ecb92c12eb49ebc3,subnet-0595f52cf6fd9b9e7 + +# セキュリティグループ(ecs-all) +{REPLACE_SG_ECS_ALL},sg-051e0fb9925539592,sg-05df4823fc789b0fa + +# セキュリティグループ(ecs-crm-datafetch) +{REPLACE_SG_CRM_DATAFETCH},sg-0b20b7bb1cb1ab886,sg-XXXXXXXXXXXXXXXXX \ No newline at end of file diff --git a/stepfunctions/TOOLS/convert_definition.py b/stepfunctions/TOOLS/convert_definition.py new file mode 100644 index 00000000..cea832e1 --- /dev/null +++ b/stepfunctions/TOOLS/convert_definition.py @@ -0,0 +1,173 @@ +import sys +import csv +import os +import re + +CONF_FOLDER_PATH = '.' +DEFINITION_FOLDER_BASE = '..' +CONVERTED_FOLDER_BASE = 'build' +CONVERT_CONF = 'convert.conf' +CHAR_CODE = 'utf-8' +PRD_NAME = 'product' +STG_NAME = 'staging' +COMMENT_PATTERN = r'(^\s*(#.*|)$)|(^(\s*|)(\r\n|\r|\n)$)' + + +def main(args=None): + try: + """ + args1: StepFunctionsステート名 + args2: 変換先環境名(product or staging) + """ + + # カレントディレクトリ移動 + os.chdir(os.path.dirname(os.path.abspath(__file__))) + + # 引数チェック + state_name, to_env = check_args(args) + + print('引数確認OK') + + # ファイル存在チェック + check_file_exist(state_name, to_env) + + print('ファイル存在確認OK') + + # 変換 + converted_file_name = convert_definition(state_name, to_env) + + print(f'変換が完了しました ファイル名:{converted_file_name}') + + return + + except Exception as e: + raise Exception(e) + + +def check_args(args): + try: + check_length(args) + + check_aws_environment(args) + + return args[1], args[2] + + except Exception as e: + raise Exception(f'引数確認に失敗しました {e}') + + +def check_length(args): + if len(args) != 3: + raise Exception('引数の数が異常です') + + return + + +def check_aws_environment(args): + if args[2] == STG_NAME or args[2] == PRD_NAME: + return + + raise Exception('第2引数が不正です') + + +def check_file_exist(state_name, to_env): + if not os.path.isfile(f'{CONF_FOLDER_PATH}/{CONVERT_CONF}'): + raise Exception('変換定義ファイルが存在しません') + + if not os.path.isfile(f'{DEFINITION_FOLDER_BASE}/{state_name}/{state_name}.json'): + raise Exception('変換元のステートメント定義が存在しません') + + if not os.path.isdir(f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{to_env}'): + os.makedirs(f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{to_env}', exist_ok=True) + + return + + +def convert_definition(state_name, to_env): + + try: + # 定義フォルダのパス生成 + from_folder = f'{DEFINITION_FOLDER_BASE}/{state_name}' + to_folder = f'{from_folder}/{CONVERTED_FOLDER_BASE}/{to_env}' + + # 変換定義のリスト化 + convert_list = set_convert_list() + + # 変換定義のTOの列番号を確認 + to_attr_num = set_attribute(to_env, convert_list) + + # 読込み、書込みファイルオープン + from_file = open(f'{from_folder}/{state_name}.json', + mode='r', encoding=CHAR_CODE) + to_file = open(f'{to_folder}/{state_name}.json', mode='w', + encoding=CHAR_CODE, newline='\n') + + # 変換元ファイルを1行ずつ読込み + for line in from_file: + # 変換定義を1要素ずつ読込み + for convert_value in convert_list: + # 変換 + line = line.replace( + convert_value[0], convert_value[to_attr_num]) + to_file.write(line) + + # 各ファイルクローズ + from_file.close() + to_file.close() + + return f'{to_folder}/{state_name}.json' + + except Exception as e: + raise Exception(f'変換に失敗しました {e}') + + +def set_convert_list(): + + try: + # 変換定義ファイルオープン + convert_conf_file = open( + f'{CONF_FOLDER_PATH}/{CONVERT_CONF}', mode='r', encoding=CHAR_CODE) + + # ファイル読込み + convert_conf = convert_conf_file.readlines() + + # 変換定義ファイルリスト化 + convert_list = [] + for row in convert_conf: + if re.match(COMMENT_PATTERN, row[0]): + continue + row = row.rstrip('\n') + data = row.split(',') + convert_list.append(data) + + convert_conf_file.close() + + return convert_list + + except Exception as e: + Exception('変換定義ファイルのリスト化に失敗しました') + + +def set_attribute(from_env, convert_list): + """ + 変換定義ファイルのどちらの列がどちらの環境かを特定 + 1列目にどちらかの環境名(product or staging)がある場合、定義内のその1列が対象の環境となる + """ + to_attr_num = None + + for attr in convert_list: + + if not attr[1] or not attr[2]: + raise Exception('変換定義が正しくありません') + + if attr[1] == from_env: + to_attr_num = 1 + + elif attr[2] == from_env: + to_attr_num = 2 + + return to_attr_num + + +if __name__ == '__main__': + main(args=sys.argv) diff --git a/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json b/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json new file mode 100644 index 00000000..f4b22be9 --- /dev/null +++ b/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json @@ -0,0 +1,129 @@ +{ + "Comment": "crm-datafetch root job", + "StartAt": "params", + "States": { + "params": { + "Comment": "パラメータ設定", + "Type": "Pass", + "Parameters": { + "sns": { + "TopicArn": "arn:aws:sns:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:nds-notice-{REPLACE_ENV_NAME}" + }, + "ecs": { + "Cluster": "arn:aws:ecs:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:cluster/mbj-newdwh2021-{REPLACE_ENV_NAME}-crm-ecs", + "LaunchType": "FARGATE", + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "Subnets": [ + "{REPLACE_SUBNET_PRI_1A}", + "{REPLACE_SUBNET_PRI_1D}" + ], + "SecurityGroups": [ + "{REPLACE_SG_ECS_ALL}", + "{REPLACE_SG_CRM_DATAFETCH}" + ], + "AssignPublicIp": "DISABLED" + } + } + } + }, + "ResultPath": "$.params", + "Next": "crm-datafetch-diff" + }, + "crm-datafetch-diff": { + "Comment": "CRMデータ取得", + "Type": "Task", + "Resource": "arn:aws:states:::ecs:runTask.sync", + "Parameters": { + "Cluster.$": "$.params.ecs.Cluster", + "LaunchType.$": "$.params.ecs.LaunchType", + "TaskDefinition": "arn:aws:ecs:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-{REPLACE_ENV_NAME}-task-crm-datafetch", + "NetworkConfiguration.$": "$.params.ecs.NetworkConfiguration" + }, + "Retry": [ + { + "ErrorEquals": ["States.ALL"], + "BackoffRate": 2, + "IntervalSeconds": 3, + "MaxAttempts": 3 + } + ], + "Catch": [ + { + "ErrorEquals": ["States.ALL"], + "ResultPath": "$.result", + "Next": "ErrorEnd" + } + ], + "ResultPath": "$.result", + "Next": "Wait" + }, + "Wait": { + "Type": "Wait", + "Seconds": 5, + "Next": "crm-datafetch-all" + }, + "crm-datafetch-all": { + "Comment": "CRMデータ全量取得", + "Type": "Task", + "Resource": "arn:aws:states:::ecs:runTask.sync", + "Parameters": { + "Cluster.$": "$.params.ecs.Cluster", + "LaunchType.$": "$.params.ecs.LaunchType", + "TaskDefinition": "arn:aws:ecs:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-{REPLACE_ENV_NAME}-task-crm-datafetch", + "NetworkConfiguration.$": "$.params.ecs.NetworkConfiguration", + "Overrides": { + "ContainerOverrides": [ + { + "Name": "mbj-newdwh2021-{REPLACE_ENV_NAME}-container-crm-datafetch", + "Environment": [ + { + "Name": "OBJECT_INFO_FILENAME", + "Value": "crm_object_list_all.json" + } + ] + } + ] + } + }, + "Retry": [ + { + "ErrorEquals": ["States.ALL"], + "BackoffRate": 2, + "IntervalSeconds": 3, + "MaxAttempts": 3 + } + ], + "Catch": [ + { + "ErrorEquals": ["States.ALL"], + "ResultPath": "$.result", + "Next": "ErrorEnd" + } + ], + "ResultPath": "$.result", + "Next": "SuccessNotice" + }, + "SuccessNotice": { + "Comment": "正常終了通知", + "Type": "Task", + "Resource": "arn:aws:states:::sns:publish", + "Parameters": { + "TopicArn.$": "$.params.sns.TopicArn", + "Subject": "StepFunctions正常終了通知", + "Message.$": "States.Format('CRMデータ取得処理が完了しました。\n\n 対象のステートマシン:{} \n 実行ID:{}', $$.StateMachine.Id, $$.Execution.Name)" + }, + "Next": "NormalEnd" + }, + "NormalEnd": { + "Comment": "正常終了", + "Type": "Succeed" + }, + "ErrorEnd": { + "Comment": "異常終了", + "Type": "Fail", + "Error": "StatesError", + "Cause": "StepFunctions ErrorEnd" + } + } +} From e850083f1f1a6d1549306d8fb6cbec8f32d1198d Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 21 Sep 2022 00:21:02 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=E5=A4=89=E6=8F=9B=E5=AE=9A?= =?UTF-8?q?=E7=BE=A9=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92yaml?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4=E3=80=82=E3=81=9D=E3=82=8C=E3=81=AB?= =?UTF-8?q?=E4=BC=B4=E3=81=84=E3=82=B9=E3=83=86=E3=83=BC=E3=83=88=E3=83=9E?= =?UTF-8?q?=E3=82=B7=E3=83=B3=E5=AE=9A=E7=BE=A9=E3=81=AE=E9=9B=9B=E5=BD=A2?= =?UTF-8?q?=E3=81=AE=E3=83=97=E3=83=AC=E3=83=BC=E3=82=B9=E3=83=9B=E3=83=AB?= =?UTF-8?q?=E3=83=80=E3=83=BC=E3=82=82=E8=8B=A5=E5=B9=B2=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stepfunctions/TOOLS/convert.conf | 24 ---- stepfunctions/TOOLS/convert_config.yaml | 32 +++++ stepfunctions/TOOLS/convert_definition.py | 127 +++++++----------- .../r-crm-datafetch-state.json | 18 +-- 4 files changed, 90 insertions(+), 111 deletions(-) delete mode 100644 stepfunctions/TOOLS/convert.conf create mode 100644 stepfunctions/TOOLS/convert_config.yaml diff --git a/stepfunctions/TOOLS/convert.conf b/stepfunctions/TOOLS/convert.conf deleted file mode 100644 index 3d62ff57..00000000 --- a/stepfunctions/TOOLS/convert.conf +++ /dev/null @@ -1,24 +0,0 @@ -# -# 各項目の第1カラムにリプレース前文字列を記載する -# 各項目の第2カラムstagingの情報を記載する -# 各項目の第3カラムにproductの情報を記載する -# 変換前文字列と変換後文字列をカンマで区切る -# - -# AWSアカウントID -{REPLACE_AWS_ACCOUNT_ID},826466435614,826466435614 - -# 環境情報 -{REPLACE_ENV_NAME},staging,product - -# サブネット(PrivateSubnet1) -{REPLACE_SUBNET_PRI_1A},subnet-0a47b12f6899ab19e,subnet-0d9bf8cd421cf2489 - -# サブネット(PrivateSubnet2) -{REPLACE_SUBNET_PRI_1D},subnet-0ecb92c12eb49ebc3,subnet-0595f52cf6fd9b9e7 - -# セキュリティグループ(ecs-all) -{REPLACE_SG_ECS_ALL},sg-051e0fb9925539592,sg-05df4823fc789b0fa - -# セキュリティグループ(ecs-crm-datafetch) -{REPLACE_SG_CRM_DATAFETCH},sg-0b20b7bb1cb1ab886,sg-XXXXXXXXXXXXXXXXX \ No newline at end of file diff --git a/stepfunctions/TOOLS/convert_config.yaml b/stepfunctions/TOOLS/convert_config.yaml new file mode 100644 index 00000000..8a49600b --- /dev/null +++ b/stepfunctions/TOOLS/convert_config.yaml @@ -0,0 +1,32 @@ +# 構成 +# config: ルートとなる要素 +# <ステートマシン名>: ステートマシン定義名 +# <環境名>: stagingかproductのみ +# <ステートマシンの雛形内のプレースホルダー名>:置き換え後の値を設定する +config: + r-crm-datafetch-state: + # ステージング環境 + staging: + # AWSアカウントID + AWS_ACCOUNT_ID: "826466435614" + # サブネット(PrivateSubnet1) + SUBNET_PRI_1A: subnet-0a47b12f6899ab19e + # サブネット(PrivateSubnet2) + SUBNET_PRI_1D: subnet-0ecb92c12eb49ebc3 + # セキュリティグループ(ecs-all) + SG_ECS_ALL: sg-051e0fb9925539592 + # セキュリティグループ(ecs-crm-datafetch) + SG_CRM_DATAFETCH: sg-0b20b7bb1cb1ab886 + # 本番環境 + product: + # AWSアカウントID + AWS_ACCOUNT_ID: "826466435614" + # サブネット(PrivateSubnet1) + SUBNET_PRI_1A: subnet-0d9bf8cd421cf2489 + # サブネット(PrivateSubnet2) + SUBNET_PRI_1D: subnet-0595f52cf6fd9b9e7 + # セキュリティグループ(ecs-all) + SG_ECS_ALL: sg-05df4823fc789b0fa + # セキュリティグループ(ecs-crm-datafetch) + # TODO: 本番環境のセキュリティグループを作成したら下記のIDを置き換える + SG_CRM_DATAFETCH: sg-XXXXXXXXXXXXXXXXX diff --git a/stepfunctions/TOOLS/convert_definition.py b/stepfunctions/TOOLS/convert_definition.py index cea832e1..eac0e088 100644 --- a/stepfunctions/TOOLS/convert_definition.py +++ b/stepfunctions/TOOLS/convert_definition.py @@ -1,22 +1,33 @@ -import sys -import csv import os -import re +import sys +from string import Template + +# you need to install module `PyYAML` +import yaml CONF_FOLDER_PATH = '.' DEFINITION_FOLDER_BASE = '..' CONVERTED_FOLDER_BASE = 'build' -CONVERT_CONF = 'convert.conf' +CONVERT_CONF = 'convert_config.yaml' CHAR_CODE = 'utf-8' PRD_NAME = 'product' STG_NAME = 'staging' -COMMENT_PATTERN = r'(^\s*(#.*|)$)|(^(\s*|)(\r\n|\r|\n)$)' +class StateMachineTemplate(Template): + """StepFunctionsステートマシンの置き換えるためのテンプレート + + 生のTemplateクラスはプレースホルダーを表す文字列が`$`で、ステートマシン定義内で常用する文字と被ってしまうため、サブクラス化 + """ + + # `#{プレースホルダー}`という形式が使えるようになる + delimiter = "#" + def __init__(self, template: str) -> None: + super().__init__(template) def main(args=None): try: """ - args1: StepFunctionsステート名 + args1: StepFunctionsステートマシン名 args2: 変換先環境名(product or staging) """ @@ -24,17 +35,23 @@ def main(args=None): os.chdir(os.path.dirname(os.path.abspath(__file__))) # 引数チェック - state_name, to_env = check_args(args) + state_name, env_name = check_args(args) print('引数確認OK') # ファイル存在チェック - check_file_exist(state_name, to_env) + check_file_exist(state_name) print('ファイル存在確認OK') + + # フォルダがなければ作る + env_name_folder = f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{env_name}' + if not os.path.isdir(env_name_folder): + os.makedirs(env_name_folder, exist_ok=True) + print(f'定義生成用フォルダを作成しました。フォルダ名:{env_name_folder}') # 変換 - converted_file_name = convert_definition(state_name, to_env) + converted_file_name = convert_definition(state_name, env_name) print(f'変換が完了しました ファイル名:{converted_file_name}') @@ -70,50 +87,37 @@ def check_aws_environment(args): raise Exception('第2引数が不正です') -def check_file_exist(state_name, to_env): +def check_file_exist(state_name): if not os.path.isfile(f'{CONF_FOLDER_PATH}/{CONVERT_CONF}'): raise Exception('変換定義ファイルが存在しません') if not os.path.isfile(f'{DEFINITION_FOLDER_BASE}/{state_name}/{state_name}.json'): - raise Exception('変換元のステートメント定義が存在しません') - - if not os.path.isdir(f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{to_env}'): - os.makedirs(f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{to_env}', exist_ok=True) + raise Exception('変換元のステートマシン定義が存在しません') return -def convert_definition(state_name, to_env): +def convert_definition(state_name, env_name): try: # 定義フォルダのパス生成 from_folder = f'{DEFINITION_FOLDER_BASE}/{state_name}' - to_folder = f'{from_folder}/{CONVERTED_FOLDER_BASE}/{to_env}' + to_folder = f'{from_folder}/{CONVERTED_FOLDER_BASE}/{env_name}' - # 変換定義のリスト化 - convert_list = set_convert_list() + # 変換定義の読み込み + convert_config = read_env_specific_config(state_name, env_name) - # 変換定義のTOの列番号を確認 - to_attr_num = set_attribute(to_env, convert_list) + # テンプレートとなるファイルを読み込み + with open(f'{from_folder}/{state_name}.json', mode='r', encoding=CHAR_CODE) as from_file: + state_json = from_file.read() + state_json_template = StateMachineTemplate(state_json) + # 環境固有の値を置き換え + substituted_state_json = state_json_template.substitute(ENV_NAME=env_name, **convert_config) - # 読込み、書込みファイルオープン - from_file = open(f'{from_folder}/{state_name}.json', - mode='r', encoding=CHAR_CODE) - to_file = open(f'{to_folder}/{state_name}.json', mode='w', - encoding=CHAR_CODE, newline='\n') - - # 変換元ファイルを1行ずつ読込み - for line in from_file: - # 変換定義を1要素ずつ読込み - for convert_value in convert_list: - # 変換 - line = line.replace( - convert_value[0], convert_value[to_attr_num]) - to_file.write(line) - - # 各ファイルクローズ - from_file.close() - to_file.close() + # 書き込みファイルオープン + with open(f'{to_folder}/{state_name}.json', mode='w', + encoding=CHAR_CODE, newline='\n') as to_file: + to_file.write(substituted_state_json) return f'{to_folder}/{state_name}.json' @@ -121,52 +125,19 @@ def convert_definition(state_name, to_env): raise Exception(f'変換に失敗しました {e}') -def set_convert_list(): +def read_env_specific_config(state_name, env_name): try: # 変換定義ファイルオープン - convert_conf_file = open( - f'{CONF_FOLDER_PATH}/{CONVERT_CONF}', mode='r', encoding=CHAR_CODE) + with open(f'{CONF_FOLDER_PATH}/{CONVERT_CONF}', mode='r', encoding=CHAR_CODE) as convert_conf_file: + config_yaml = yaml.load(convert_conf_file, yaml.Loader) - # ファイル読込み - convert_conf = convert_conf_file.readlines() - - # 変換定義ファイルリスト化 - convert_list = [] - for row in convert_conf: - if re.match(COMMENT_PATTERN, row[0]): - continue - row = row.rstrip('\n') - data = row.split(',') - convert_list.append(data) - - convert_conf_file.close() - - return convert_list + # 変換定義からステートマシンの環境固有の値を取得 + env_specific_config = config_yaml['config'][state_name][env_name] + return env_specific_config except Exception as e: - Exception('変換定義ファイルのリスト化に失敗しました') - - -def set_attribute(from_env, convert_list): - """ - 変換定義ファイルのどちらの列がどちらの環境かを特定 - 1列目にどちらかの環境名(product or staging)がある場合、定義内のその1列が対象の環境となる - """ - to_attr_num = None - - for attr in convert_list: - - if not attr[1] or not attr[2]: - raise Exception('変換定義が正しくありません') - - if attr[1] == from_env: - to_attr_num = 1 - - elif attr[2] == from_env: - to_attr_num = 2 - - return to_attr_num + Exception('変換定義ファイルの読み込みに失敗しました') if __name__ == '__main__': diff --git a/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json b/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json index f4b22be9..977c1bbc 100644 --- a/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json +++ b/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json @@ -7,20 +7,20 @@ "Type": "Pass", "Parameters": { "sns": { - "TopicArn": "arn:aws:sns:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:nds-notice-{REPLACE_ENV_NAME}" + "TopicArn": "arn:aws:sns:ap-northeast-1:#{AWS_ACCOUNT_ID}:nds-notice-#{ENV_NAME}" }, "ecs": { - "Cluster": "arn:aws:ecs:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:cluster/mbj-newdwh2021-{REPLACE_ENV_NAME}-crm-ecs", + "Cluster": "arn:aws:ecs:ap-northeast-1:#{AWS_ACCOUNT_ID}:cluster/mbj-newdwh2021-#{ENV_NAME}-crm-ecs", "LaunchType": "FARGATE", "NetworkConfiguration": { "AwsvpcConfiguration": { "Subnets": [ - "{REPLACE_SUBNET_PRI_1A}", - "{REPLACE_SUBNET_PRI_1D}" + "#{SUBNET_PRI_1A}", + "#{SUBNET_PRI_1D}" ], "SecurityGroups": [ - "{REPLACE_SG_ECS_ALL}", - "{REPLACE_SG_CRM_DATAFETCH}" + "#{SG_ECS_ALL}", + "#{SG_CRM_DATAFETCH}" ], "AssignPublicIp": "DISABLED" } @@ -37,7 +37,7 @@ "Parameters": { "Cluster.$": "$.params.ecs.Cluster", "LaunchType.$": "$.params.ecs.LaunchType", - "TaskDefinition": "arn:aws:ecs:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-{REPLACE_ENV_NAME}-task-crm-datafetch", + "TaskDefinition": "arn:aws:ecs:ap-northeast-1:#{AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-#{ENV_NAME}-task-crm-datafetch", "NetworkConfiguration.$": "$.params.ecs.NetworkConfiguration" }, "Retry": [ @@ -70,12 +70,12 @@ "Parameters": { "Cluster.$": "$.params.ecs.Cluster", "LaunchType.$": "$.params.ecs.LaunchType", - "TaskDefinition": "arn:aws:ecs:ap-northeast-1:{REPLACE_AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-{REPLACE_ENV_NAME}-task-crm-datafetch", + "TaskDefinition": "arn:aws:ecs:ap-northeast-1:#{AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-#{ENV_NAME}-task-crm-datafetch", "NetworkConfiguration.$": "$.params.ecs.NetworkConfiguration", "Overrides": { "ContainerOverrides": [ { - "Name": "mbj-newdwh2021-{REPLACE_ENV_NAME}-container-crm-datafetch", + "Name": "mbj-newdwh2021-#{ENV_NAME}-container-crm-datafetch", "Environment": [ { "Name": "OBJECT_INFO_FILENAME", From 34c35c81ced09f79a8987a18eb05fc886b9649e5 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 21 Sep 2022 00:21:20 +0900 Subject: [PATCH 3/5] =?UTF-8?q?docs:=20README=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stepfunctions/README.md | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 stepfunctions/README.md diff --git a/stepfunctions/README.md b/stepfunctions/README.md new file mode 100644 index 00000000..361689c8 --- /dev/null +++ b/stepfunctions/README.md @@ -0,0 +1,57 @@ +# AWS StepFunctions + +## 概要 + +- MeDaCa基板上でバッチ処理を行うStepFunctionsステートマシン定義を格納する +- ステートマシン定義を格納する際のフォルダ構成は以下とする + - `ステートマシン名/ステートマシン名.json` +- Git管理するファイルは雛形とし、実際の環境にデプロイする定義は`/TOOLS`フォルダ内のツールで生成したものを使用する +- ステートマシン定義の雛形内の環境固有の値は`#{値を表すキー名}`の形式で記述すること + +## バージョン情報 + +- Python3.9.x + +## フォルダ構成 + +```text +. +├── TOOLS -- 環境ごとのステートマシン定義生成ツール置き場 +│   ├── convert.conf.yaml -- ステートマシンの変換定義ファイル +│   ├── convert_definition.py -- 定義変換ツールの本体 +└── r-crm-datafetch-state -- CRMデータ取得処理のステートマシン定義置き場 + ├── build -- 【Git管理対象外】TOOLSによって生成され、環境名のフォルダに、環境ごとの値に置き換えたステートマシン定義を配置する + │   ├── product + │   └── staging + └── r-crm-datafetch-state.json -- CRMデータ取得処理のステートマシン定義 +``` + +## ツールの利用方法 + +### 事前準備 + +- `/TOOLS`フォルダに移動し、以下のコマンドを実行して、Pythonの仮想環境を作成する + +```sh +cd ./TOOLS +# 仮想環境を作成 +python -m venv ./.venv +# 仮想環境を有効化 +# Mac/Linuxの場合 +source ./.venv/bin/activate +# Windowsの場合 +.\.venv\Scripts\activate +``` + +- 以下のコマンドを実行し、YAMLのパッケージをインストールする + +```sh +pip install PyYAML +``` + +### 起動方法 + +```sh +cd ./TOOLS +python convert_definition.py r-crm-datafetch-state staging +``` From 78983826244cf76fc2f00d72b2cf4aa2ebb5b63d Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Wed, 21 Sep 2022 08:44:39 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20=E6=97=A9=E6=9C=9Freturn?= =?UTF-8?q?=E5=8C=96=E3=80=81main=E9=96=A2=E6=95=B0=E3=81=AF=E5=8F=97?= =?UTF-8?q?=E3=81=91=E5=8F=96=E3=81=A3=E3=81=9F=E4=BE=8B=E5=A4=96=E3=82=92?= =?UTF-8?q?=E6=8A=95=E3=81=92=E3=81=A6=E3=81=84=E3=82=8B=E3=81=A0=E3=81=91?= =?UTF-8?q?=E3=81=AA=E3=81=AE=E3=81=A7try-except=E3=82=92=E3=81=AA?= =?UTF-8?q?=E3=81=8F=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stepfunctions/TOOLS/convert_definition.py | 57 +++++++++++------------ 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/stepfunctions/TOOLS/convert_definition.py b/stepfunctions/TOOLS/convert_definition.py index eac0e088..aead3f47 100644 --- a/stepfunctions/TOOLS/convert_definition.py +++ b/stepfunctions/TOOLS/convert_definition.py @@ -25,40 +25,36 @@ class StateMachineTemplate(Template): super().__init__(template) def main(args=None): - try: - """ - args1: StepFunctionsステートマシン名 - args2: 変換先環境名(product or staging) - """ + """ + args1: StepFunctionsステートマシン名 + args2: 変換先環境名(product or staging) + """ - # カレントディレクトリ移動 - os.chdir(os.path.dirname(os.path.abspath(__file__))) + # カレントディレクトリ移動 + os.chdir(os.path.dirname(os.path.abspath(__file__))) - # 引数チェック - state_name, env_name = check_args(args) + # 引数チェック + state_name, env_name = check_args(args) - print('引数確認OK') + print('引数確認OK') - # ファイル存在チェック - check_file_exist(state_name) + # ファイル存在チェック + check_file_exist(state_name) - print('ファイル存在確認OK') - - # フォルダがなければ作る - env_name_folder = f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{env_name}' - if not os.path.isdir(env_name_folder): - os.makedirs(env_name_folder, exist_ok=True) - print(f'定義生成用フォルダを作成しました。フォルダ名:{env_name_folder}') + print('ファイル存在確認OK') + + # フォルダがなければ作る + env_name_folder = f'{DEFINITION_FOLDER_BASE}/{state_name}/{CONVERTED_FOLDER_BASE}/{env_name}' + if not os.path.isdir(env_name_folder): + os.makedirs(env_name_folder, exist_ok=True) + print(f'定義生成用フォルダを作成しました。フォルダ名:{env_name_folder}') - # 変換 - converted_file_name = convert_definition(state_name, env_name) + # 変換 + converted_file_name = convert_definition(state_name, env_name) - print(f'変換が完了しました ファイル名:{converted_file_name}') + print(f'変換が完了しました ファイル名:{converted_file_name}') - return - - except Exception as e: - raise Exception(e) + return def check_args(args): @@ -81,10 +77,11 @@ def check_length(args): def check_aws_environment(args): - if args[2] == STG_NAME or args[2] == PRD_NAME: - return + if args[2] not in [STG_NAME, PRD_NAME]: + raise Exception('第2引数が不正です') + + return - raise Exception('第2引数が不正です') def check_file_exist(state_name): @@ -116,7 +113,7 @@ def convert_definition(state_name, env_name): # 書き込みファイルオープン with open(f'{to_folder}/{state_name}.json', mode='w', - encoding=CHAR_CODE, newline='\n') as to_file: + encoding=CHAR_CODE, newline='\n') as to_file: to_file.write(substituted_state_json) return f'{to_folder}/{state_name}.json' From f0bcdc293b3b7e50dca598a823d5d59321a2c074 Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Thu, 22 Sep 2022 16:12:10 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=E5=A4=89=E6=8F=9B=E5=AE=9A=E7=BE=A9?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=EF=BC=88yaml=EF=BC=89?= =?UTF-8?q?=E3=81=AE=E4=BB=95=E6=A7=98=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stepfunctions/TOOLS/convert_config.yaml | 54 +++++++++++++++---- stepfunctions/TOOLS/convert_definition.py | 1 + .../r-crm-datafetch-state.json | 8 +-- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/stepfunctions/TOOLS/convert_config.yaml b/stepfunctions/TOOLS/convert_config.yaml index 8a49600b..2b6487ea 100644 --- a/stepfunctions/TOOLS/convert_config.yaml +++ b/stepfunctions/TOOLS/convert_config.yaml @@ -3,30 +3,62 @@ # <ステートマシン名>: ステートマシン定義名 # <環境名>: stagingかproductのみ # <ステートマシンの雛形内のプレースホルダー名>:置き換え後の値を設定する +resource: + # 共通定義 + common: + # AWSアカウントID + - &AWS_ACCOUNT_ID "826466435614" + # 東京リージョン + - ®ION_AP_NORTHEAST_1 "ap-northeast-1" + # ステージング環境 + staging: + # サブネット(PrivateSubnet1) + - &STG_SUBNET_PRI_1A "subnet-0a47b12f6899ab19e" + # サブネット(PrivateSubnet2) + - &STG_SUBNET_PRI_1D "subnet-0ecb92c12eb49ebc3" + # セキュリティグループ(ecs-all) + - &STG_SG_ECS_ALL "sg-051e0fb9925539592" + # セキュリティグループ(ecs-crm-datafetch) + - &STG_SG_CRM_DATAFETCH "sg-0b20b7bb1cb1ab886" + # 本番環境 + product: + # サブネット(PrivateSubnet1) + - &PRD_SUBNET_PRI_1A "subnet-0d9bf8cd421cf2489" + # サブネット(PrivateSubnet2) + - &PRD_SUBNET_PRI_1D "subnet-0595f52cf6fd9b9e7" + # セキュリティグループ(ecs-all) + - &PRD_SG_ECS_ALL "sg-05df4823fc789b0fa" + # セキュリティグループ(ecs-crm-datafetch) + # TODO: 本番環境のセキュリティグループを作成したら下記のIDを置き換える + - &PRD_SG_CRM_DATAFETCH "sg-XXXXXXXXXXXXXXXXX" + config: r-crm-datafetch-state: # ステージング環境 staging: # AWSアカウントID - AWS_ACCOUNT_ID: "826466435614" + AWS_ACCOUNT_ID: *AWS_ACCOUNT_ID + # 東京リージョン + REGION_AP_NORTHEAST_1: *REGION_AP_NORTHEAST_1 # サブネット(PrivateSubnet1) - SUBNET_PRI_1A: subnet-0a47b12f6899ab19e + SUBNET_PRI_1A: *STG_SUBNET_PRI_1A # サブネット(PrivateSubnet2) - SUBNET_PRI_1D: subnet-0ecb92c12eb49ebc3 + SUBNET_PRI_1D: *STG_SUBNET_PRI_1D # セキュリティグループ(ecs-all) - SG_ECS_ALL: sg-051e0fb9925539592 + SG_ECS_ALL: *STG_SG_ECS_ALL # セキュリティグループ(ecs-crm-datafetch) - SG_CRM_DATAFETCH: sg-0b20b7bb1cb1ab886 + SG_CRM_DATAFETCH: *STG_SG_CRM_DATAFETCH # 本番環境 product: # AWSアカウントID - AWS_ACCOUNT_ID: "826466435614" + AWS_ACCOUNT_ID: *AWS_ACCOUNT_ID + # 東京リージョン + REGION_AP_NORTHEAST_1: *REGION_AP_NORTHEAST_1 # サブネット(PrivateSubnet1) - SUBNET_PRI_1A: subnet-0d9bf8cd421cf2489 + SUBNET_PRI_1A: *PRD_SUBNET_PRI_1A # サブネット(PrivateSubnet2) - SUBNET_PRI_1D: subnet-0595f52cf6fd9b9e7 + SUBNET_PRI_1D: *PRD_SUBNET_PRI_1D # セキュリティグループ(ecs-all) - SG_ECS_ALL: sg-05df4823fc789b0fa + SG_ECS_ALL: *PRD_SG_ECS_ALL # セキュリティグループ(ecs-crm-datafetch) - # TODO: 本番環境のセキュリティグループを作成したら下記のIDを置き換える - SG_CRM_DATAFETCH: sg-XXXXXXXXXXXXXXXXX + SG_CRM_DATAFETCH: *PRD_SG_CRM_DATAFETCH diff --git a/stepfunctions/TOOLS/convert_definition.py b/stepfunctions/TOOLS/convert_definition.py index aead3f47..4297e703 100644 --- a/stepfunctions/TOOLS/convert_definition.py +++ b/stepfunctions/TOOLS/convert_definition.py @@ -103,6 +103,7 @@ def convert_definition(state_name, env_name): # 変換定義の読み込み convert_config = read_env_specific_config(state_name, env_name) + print(convert_config) # テンプレートとなるファイルを読み込み with open(f'{from_folder}/{state_name}.json', mode='r', encoding=CHAR_CODE) as from_file: diff --git a/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json b/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json index 977c1bbc..f1d3bf4f 100644 --- a/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json +++ b/stepfunctions/r-crm-datafetch-state/r-crm-datafetch-state.json @@ -7,10 +7,10 @@ "Type": "Pass", "Parameters": { "sns": { - "TopicArn": "arn:aws:sns:ap-northeast-1:#{AWS_ACCOUNT_ID}:nds-notice-#{ENV_NAME}" + "TopicArn": "arn:aws:sns:#{REGION_AP_NORTHEAST_1}:#{AWS_ACCOUNT_ID}:nds-notice-#{ENV_NAME}" }, "ecs": { - "Cluster": "arn:aws:ecs:ap-northeast-1:#{AWS_ACCOUNT_ID}:cluster/mbj-newdwh2021-#{ENV_NAME}-crm-ecs", + "Cluster": "arn:aws:ecs:#{REGION_AP_NORTHEAST_1}:#{AWS_ACCOUNT_ID}:cluster/mbj-newdwh2021-#{ENV_NAME}-crm-ecs", "LaunchType": "FARGATE", "NetworkConfiguration": { "AwsvpcConfiguration": { @@ -37,7 +37,7 @@ "Parameters": { "Cluster.$": "$.params.ecs.Cluster", "LaunchType.$": "$.params.ecs.LaunchType", - "TaskDefinition": "arn:aws:ecs:ap-northeast-1:#{AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-#{ENV_NAME}-task-crm-datafetch", + "TaskDefinition": "arn:aws:ecs:#{REGION_AP_NORTHEAST_1}:#{AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-#{ENV_NAME}-task-crm-datafetch", "NetworkConfiguration.$": "$.params.ecs.NetworkConfiguration" }, "Retry": [ @@ -70,7 +70,7 @@ "Parameters": { "Cluster.$": "$.params.ecs.Cluster", "LaunchType.$": "$.params.ecs.LaunchType", - "TaskDefinition": "arn:aws:ecs:ap-northeast-1:#{AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-#{ENV_NAME}-task-crm-datafetch", + "TaskDefinition": "arn:aws:ecs:#{REGION_AP_NORTHEAST_1}:#{AWS_ACCOUNT_ID}:task-definition/mbj-newdwh2021-#{ENV_NAME}-task-crm-datafetch", "NetworkConfiguration.$": "$.params.ecs.NetworkConfiguration", "Overrides": { "ContainerOverrides": [