EC2(Classic)の起動/停止自動化で詰まった問題(EC2のElasticIPが割当解除される)とその解決方法を共有します。
1.EC2のIPアドレス
EC2には、グローバルIPとプライベートIPという2つのIPアドレスが割振られています。
・グローバルIP:インターネットから参照可能なIP
・プライベートIP:AWS同一リージョン内で参照可能なIP
プライベートIPは常に変わりませんが、グローバルIPはEC2停止の度に変更されます。
かといってEC2を起動しっぱなしにしては1日中課金され続けます。EC2+ストレージの費用はなかなかの金額です、、
そのため、AWSにはElasticIPというグローバルIPを固定するサービスが用意されています。
2.ElasticIP
ElasticIPは、固定のグローバルIPを発行/割当できるAWSサービスです。
これによりEC2が停止する度にグローバルIPの変更を避けられます。
ところがEC2のプラットフォームによりElasticIPは効果がなくなります。料金もほぼ無料です。
3.EC2のプラットフォーム
EC2には、「EC2-Classic」「EC-VPC」というプラットフォームがあります。
・EC2-Classic:リージョン内に構築されるEC2
・EC2-VPC:EC2内の特定のネットワークに構築されるEC2
ElasticIPはどちらのプラットフォームでも使用可能です。
以下の図では1~4がClassic、5~6がVPCです。
ところが、EC2-ClassicではEC2停止時にElasticIP割当が解除されます。
グローバルIPの固定が目的なのに、結果的グローバルIPは変わってしまいます。
4.LambdaでElasticIP割当
そこで考えた対策は、LambdaによるElasticIP自動割当です。
LambdaでEC2自動起動+ElasticIP割当まで行いました。
※ソースコードは以下ブログのコードを参考にさせていただきました。
Lambdaなど詳細は以下参考ください。
https://dev.classmethod.jp/cloud/aws/simple-auto-start-stop-for-ec2/
import boto3
def lambda_handler(event, context):
region = event['Region']
instances = event['Instances']
ec2 = boto3.client('ec2', region_name=region)
if event['Action'] == 'start':
ec2.start_instances(InstanceIds=instances)
ec2.associate_address(
InstanceIds=instances,
PublicIp='XX.XXX.XXX.XXX',
)
print 'started your instances: ' + ", ".join(instances)
elif event['Action'] == 'stop':
ec2.stop_instances(InstanceIds=instances)
print 'stopped your instances: ' + ", ".join(instances)
以下がグローバルIP割当部です。
XX.XXX.XXX.XXXの部分に直接ElasticIPで発行した固定IPを記入ください。
ec2.associate_address(
InstanceIds=instances,
PublicIp='XX.XXX.XXX.XXX',
)
これでEC2-ClassicでもグローバルIPの固定化が実現できました。