2개 답변
- 최신
- 최다 투표
- 가장 많은 댓글
0
はい、可能です。
コードは以下のようになります。(例外処理などは入れていません)
以下のコードではアラームになったらEC2をターゲットグループから外して、停止していた2台目のEC2を起動後にターゲットグループへアタッチするコードになっています。
最後にターゲットグループから外したEC2を停止するようにしています。
また、EC2をターゲットグループにアタッチするためにEC2のステータスが「running」になるまで無限ループさせています。
なので、Lambdaの実行時間を1分程度に変更するようにしてください。
LambdaのIAMロールにはとりあえず「AmazonEC2FullAccess」をアタッチしておけば動作させることが可能です。
import boto3
import json
import time
elbv2_client = boto3.client('elbv2')
ec2_client = boto3.client('ec2')
instance_id1 = '1台目のインスタンスID'
instance_id2 = '2台目のインスタンスID'
target_group_arn = 'ターゲットグループのARN'
def lambda_handler(event, context):
Message = json.loads(event['Records'][0]['Sns']['Message'])
deregister_instance_id = Message['Trigger']['Dimensions'][0]['value']
# アラートになったのが1台目のEC2の場合の処理
if deregister_instance_id == instance_id1:
elbv2_client.deregister_targets(
TargetGroupArn=target_group_arn,
Targets=[
{
'Id': deregister_instance_id,
},
]
)
# 2台目のインスタンスを起動
ec2_client.start_instances(
InstanceIds=[instance_id2]
)
# 2台目のインスタンスが起動するまで無限ループさせる
while True:
time.sleep(3)
response = ec2_client.describe_instance_status(
InstanceIds=[instance_id2]
)
if len(response['InstanceStatuses']) > 0:
instance_status = response['InstanceStatuses'][0]['InstanceState']['Name']
if instance_status == 'running':
break
# ターゲットグループへアタッチ
elbv2_client.register_targets(
TargetGroupArn=target_group_arn,
Targets=[
{
'Id': instance_id2,
},
]
)
# 1台目のインスタンスを停止
ec2_client.stop_instances(
InstanceIds=[deregister_instance_id]
)
# アラートになったのが2台目のEC2の場合の処理
else:
elbv2_client.deregister_targets(
TargetGroupArn=target_group_arn,
Targets=[
{
'Id': deregister_instance_id,
},
]
)
# 1台目のインスタンスを起動
ec2_client.start_instances(
InstanceIds=[instance_id1]
)
# 2台目のインスタンスが起動するまで無限ループさせる
while True:
time.sleep(3)
response = ec2_client.describe_instance_status(
InstanceIds=[instance_id1]
)
if len(response['InstanceStatuses']) > 0:
instance_status = response['InstanceStatuses'][0]['InstanceState']['Name']
if instance_status == 'running':
break
# ターゲットグループへアタッチ
elbv2_client.register_targets(
TargetGroupArn=target_group_arn,
Targets=[
{
'Id': instance_id1,
},
]
)
# 2台目のインスタンスを停止
ec2_client.stop_instances(
InstanceIds=[deregister_instance_id]
)
0
ご返信ありがとうございます。(文字数制限で貼り付けられなかったのでスレッドを変更しました)
コードを修正しました。
以下のコードを使用すると、1台目のEC2が紐づいているターゲットグループから2台目のEC2が紐づいているターゲットグループに切り替わります。
また、使用していないスタンバイのEC2については停止した状態で使用してください。(途中で起動するコードを入れているので起動したままだとエラーになります)
import boto3
import json
import time
elbv2_client = boto3.client('elbv2')
ec2_client = boto3.client('ec2')
instance_id1 = '1台目のインスタンスID'
instance_id2 = '2台目のインスタンスID'
target_group_arn1 = '1台目のインスタンスが紐づいたターゲットグループのARN'
target_group_arn2 = '2台目のインスタンスが紐づいたターゲットグループのARN'
listener_arn = '変更するリスナーのARN'
def lambda_handler(event, context):
Message = json.loads(event['Records'][0]['Sns']['Message'])
deregister_instance_id = Message['Trigger']['Dimensions'][0]['value']
# アラートになったのが1台目のEC2の場合の処理
if deregister_instance_id == instance_id1:
elbv2_client.modify_listener(
ListenerArn=listener_arn,
DefaultActions=[
{
'Type': 'forward',
'TargetGroupArn': target_group_arn2,
},
]
)
# 2台目のインスタンスを起動
ec2_client.start_instances(
InstanceIds=[instance_id2]
)
# 1台目のインスタンスを停止
ec2_client.stop_instances(
InstanceIds=[deregister_instance_id]
)
# アラートになったのが2台目のEC2の場合の処理
else:
elbv2_client.modify_listener(
ListenerArn=listener_arn,
DefaultActions=[
{
'Type': 'forward',
'TargetGroupArn': target_group_arn1,
},
]
)
# 1台目のインスタンスを起動
ec2_client.start_instances(
InstanceIds=[instance_id1]
)
# 2台目のインスタンスを停止
ec2_client.stop_instances(
InstanceIds=[deregister_instance_id]
)
追記ありがとうございます。上記を参考に想定していた挙動を行うことができました。 ご回答ありがとうございました。
관련 콘텐츠
- 질문됨 2달 전
- 질문됨 10달 전
- AWS 공식업데이트됨 일 년 전
- AWS 공식업데이트됨 3년 전
- AWS 공식업데이트됨 일 년 전
ご回答ありがとうございます。 自分の説明不足な部分がありました。 こちらのコードでは1つのターゲットグループのec2に対して変更を行う設定となっていると思いますが、 要件といたしましては前提としてターゲットグループはすでにスタンバイ側も作成しており、ターゲットグループが2つ存在している状態です。 albのリスナールールでデフォルトのルールでターゲットを稼働中のec2が紐づけられているターゲットグループ1を指定しています。 このターゲットグループを予め作成してあるスタンバイ側が紐づいているターゲットグループ2に変更したいという要件になります。 GUIで操作するとロードバランサーのルール編集からターゲットグループを変更する設定です。