この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
boto3 で楽しむ AWS PythonLife 一人AdventCalendarです。
boto3のドキュメントを通して、サービス別にどういった事が出来るのかを理解したり、管理コンソールを通さずにTerminalだけで完結できるように検証していくことが目的になります。
3日目はLightsailのインスタンスを対話ベースでの作成を試してみました。
目次
boto3を通してLightsailで出来ること
ドキュメントは下記リンク先です。
ざっくりと以下のことができます。
- インスタンスの操作(作成・削除・スナップショット・StaticIP設定)
- ディスクの操作(作成・削除・スナップショット)
- リレーショナル・データベースの操作(作成・削除)
今回の操作
対話ベースでパラメータを指定して、インスタンスを作成します。
- blueprint_idの指定
- bundle_idの指定
- インスタンス名の指定
- リージョンの指定
- インスタンスの作成
dryrun
オプションを指定すると作成は行いません。
% python main.py
Input Profile name [default]>>advent_calendar
Select blueprint
[0] windows_server_2016_2018_10_14
[1] windows_server_2012_2018_10_14
[2] windows_server_2016_sql_2016_express_2018_10_14
[3] amazon_linux_2018_03_0_2
[4] ubuntu_16_04_2
[5] ubuntu_18_04
[6] debian_8_7
[7] debian_9_5
[8] freebsd_11_1
[9] opensuse_42_2
[10] centos_7_1805_01
[11] wordpress_4_9_8
[12] wordpress_multisite_4_9_8
[13] lamp_5_6_37_2
[14] lamp_7_1_20_1
[15] nodejs_10_8_0
[16] joomla_3_8_11
[17] magento_2_2_5
[18] mean_4_0_1
[19] drupal_8_5_6
[20] gitlab_11_1_4_1
[21] redmine_3_4_6
[22] nginx_1_14_0_1
[23] plesk_ubuntu_17_8_11_1
>>3
Select bundle
[0] nano_2_0
[1] micro_2_0
[2] small_2_0
[3] medium_2_0
[4] large_2_0
[5] xlarge_2_0
[6] 2xlarge_2_0
[7] nano_win_2_0
[8] micro_win_2_0
[9] small_win_2_0
[10] medium_win_2_0
[11] large_win_2_0
[12] xlarge_win_2_0
[13] 2xlarge_win_2_0
>>0
Input Instance name >>test
Select region
[0] ap-northeast-1a
[1] ap-northeast-1c
[2] ap-northeast-1d
>>0
test : Started
main.py
import boto3
import subprocess
import argparse
class LightsailWizard:
_client_name = 'lightsail'
_session = None
def __init__(self, profile_name):
self._session = boto3.Session(profile_name=profile_name)
@property
def session(self):
return self._session
@property
def client(self):
return self.session.client(self.client_name)
@property
def client_name(self):
return self._client_name
def get_blueprint_ids(self, **kwargs):
res = self.client.get_blueprints(**kwargs)
return [blueprint['blueprintId'] for blueprint in res['blueprints']]
def get_bundle_ids(self, **kwargs):
res = self.client.get_bundles(**kwargs)
return [bundle['bundleId'] for bundle in res['bundles']]
def get_regions(self, **kwargs):
kwargs.update({'includeAvailabilityZones':True})
res = self.client.get_regions(**kwargs)
zone_names = list()
for region in res['regions']:
for zone in region['availabilityZones']:
zone_names.append(zone['zoneName'])
return zone_names
def create_instance(self, instance_name, availability_zone, blueprint_id, bundle_id):
params = {
'instanceNames': [instance_name],
'availabilityZone': availability_zone,
'blueprintId': blueprint_id,
'bundleId': bundle_id
}
lightsail = self.client
res = lightsail.create_instances(**params)
for ope in res['operations']:
print("{name} : {status}".format(name=ope['resourceName'], status=ope['status']))
@classmethod
def prompt_instance_name(cls):
instance_name = None
while True:
instance_name = input('Input Instance name >>')
if instance_name and len(instance_name) != 0:
break
return instance_name
def prompt_availability_zone(self):
region_name = None
while True:
print('\nSelect region')
region_names = self.get_regions()
for region_name in region_names:
print('[{}] {}'.format(region_names.index(region_name), region_name))
index = input('>> ')
if len(index) != 0 and int(index) < len(region_names):
region_name = region_names[int(index)]
break
return region_name
def prompt_blueprint(self):
blueprint_id = None
while True:
print('\nSelect blueprint')
blueprint_ids = self.get_blueprint_ids()
for blueprint_id in blueprint_ids:
print('[{}] {}'.format(blueprint_ids.index(blueprint_id), blueprint_id))
index = input('>> ')
if len(index) != 0 and int(index) < len(blueprint_ids):
blueprint_id = blueprint_ids[int(index)]
break
return blueprint_id
def prompt_bundle(self):
bundle_id = None
while True:
print('\nSelect bundle')
bundle_ids = self.get_bundle_ids()
for bundle_id in bundle_ids:
print('[{}] {}'.format(bundle_ids.index(bundle_id), bundle_id))
index = input('>> ')
if len(index) != 0 and int(index) < len(bundle_ids):
bundle_id = bundle_ids[int(index)]
break
return bundle_id
@staticmethod
def prompt(dryrun=True):
if dryrun:
print("dryrun-mode")
params = {}
default_profile_name = 'default'
profile_name = input('Input Profile name [{}]>> '.format(default_profile_name))
if len(profile_name) == 0:
profile_name = default_profile_name
wizard = LightsailWizard(profile_name)
blueprint_id = wizard.prompt_blueprint()
bundle_id = wizard.prompt_bundle()
instance_name = wizard.prompt_instance_name()
region_name = wizard.prompt_availability_zone()
if dryrun:
result_format = "instance_name: {}, region_name: {}, blueprint_id: {}, bundle_id: {}"
print(result_format.format(instance_name, region_name, blueprint_id, bundle_id))
return
wizard.create_instance(instance_name, region_name, blueprint_id, bundle_id)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--dryrun', action='store_true')
args = parser.parse_args()
LightsailWizard.prompt(args.dryrun)
get_region
インスタンス生成時に必要なリージョン名取得はincludeAvailabilityZones=True
の指定が必要です。
まとめ
Lightsail用のコマンドを通して、お手軽インスタンス生成のロジックを組んでみました。細かいパラメータを指定できるようにすると、色々と対応可能な幅も広がると思います。
なお、今回のロジックはインスタンスを作成するだけで削除しません。作成したインスタンスが必要なければ忘れずに削除しておきましょう。