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",