Python×boto3のAWS自動化方法|EC2・S3操作入門

※本記事にはプロモーションを含む場合があります。
- boto3の導入はわずか3ステップ、初回セットアップは10分程度で完了
- IAMロール認証を使えばアクセスキー管理が不要になり、漏洩リスクを大幅に低減できるとされています
- EC2の停止し忘れ1台でも月額3,000円前後の無駄なコストが発生するケースがあります
- S3のライフサイクル設定でストレージコストを最大40%圧縮できるといわれています
- Lambda連携により24時間365日の完全自動運用が可能になります
なぜ自動化が必要か
AWSインフラの手動運用には、見えにくいコストが積み重なっています。たとえばt2.microインスタンスを1台停止し忘れただけでも、月額換算で約3,000円前後の課金が発生し続けます。これが10台、100台規模になると、年間で数十万円単位の無駄が積み上がることになります。
加えて、AWSコンソールでの手動操作は1回あたり平均10〜15分かかるとされ、同じ作業を1日に何度も繰り返すエンジニアにとっては大きな時間的負担です。Pythonとboto3を使ったスクリプトであれば、同じ処理を数秒〜数十秒で完了させられます。仮に1日100回同様の操作が発生する運用現場であれば、自動化によって作業時間を70%以上削減できたという報告も見られます。
再現性の観点でも手動運用には弱点があります。人の手で設定する以上、同じ手順を100回繰り返しても微妙な設定差異が生まれる可能性があります。スクリプト化しておけば、開発環境・検証環境・本番環境で同一のコードを実行するだけで、寸分違わぬ構成を再現できます。
スケーラビリティも見逃せないポイントです。手動で100台のEC2インスタンスを管理するのは現実的ではなく、担当者の負荷は指数関数的に増えていきます。自動化スクリプトであれば、対象インスタンスのリストを渡すだけで数千台規模でも数分で処理が完了します。AWSが公開している資料でも、俊敏性とコスト削減の両立には自動化が欠かせない要素として位置づけられています。
boto3導入は3ステップ
boto3はAWSが公式に提供するPython用SDKで、Pythonコードから直接AWSの各サービスを呼び出せるようにするライブラリです。導入までの流れは、大きく分けて3ステップで完了します。
- pip経由でboto3をインストールする(所要時間は1〜2分程度)
- AWS認証情報(IAMユーザーまたはIAMロール)を設定する
- 簡単なスクリプトを実行して疎通確認を行う
インストールコマンドは以下の通りです。
pip install boto3プロジェクトによってはバージョンを固定したいケースもあります。その場合は以下のようにバージョン番号を指定します。
pip install boto3==1.26.0インストールと同時にbotocoreというライブラリも導入されます。botocoreはAPIリクエストの低レベルな処理を担う部分で、boto3の内部で密接に連携して動作しています。インストール後は以下のコマンドでバージョンを確認できます。
python -c "import boto3; print(boto3.__version__)"次に認証情報の設定です。boto3を使ってAWSリソースを操作するには、IAMユーザーによる認証とIAMロールによる認証の2通りの方法があります。それぞれの特徴を比較すると以下のようになります。
| 比較項目 | IAMユーザー認証 | IAMロール認証 |
|---|---|---|
| 鍵の管理 | アクセスキー・シークレットキーを保管する必要あり | 鍵の管理が不要 |
| 漏洩リスク | キーがコードや環境変数に残ると漏洩の可能性あり | 一時的な認証情報が自動発行されるため低リスク |
| ローテーション | 90日ごとの手動更新が推奨されるケースが多い | 自動でローテーションされる |
| 向いている用途 | ローカル開発、CI/CD環境 | EC2・Lambdaなどクラウド上で動くスクリプト |
| 費用 | 0円(追加費用なし) | 0円(追加費用なし) |
IAMユーザーで認証する場合、以下の3通りの設定方法があります。
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=ap-northeast-1[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region = ap-northeast-1import boto3
session = boto3.Session(
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
region_name='ap-northeast-1'
)
ec2 = session.client('ec2')コード内に直接キーを書き込む方法は、GitHubなど公開リポジトリへの誤コミットで漏洩する事故が起きやすいポイントです。万一漏洩に気づいた場合は、IAMコンソールから該当キーを速やかに無効化する対応が推奨されています。EC2やLambda上で動作させるスクリプトについては、IAMロールを使う方法が安全性の面で優位とされています。
基本的な構文は「クライアントまたはリソースオブジェクトの作成」→「API呼び出し」→「レスポンス処理」という3ステップの流れです。以下はEC2インスタンス一覧を取得するサンプルです。
import boto3
ec2 = boto3.client('ec2')
response = ec2.describe_instances()
for reservation in response['Reservations']:
for instance in reservation['Instances']:
print(f"Instance ID: {instance['InstanceId']}")
print(f"Instance Type: {instance['InstanceType']}")
print(f"State: {instance['State']['Name']}")より高レベルなインターフェースが欲しい場合はresourceオブジェクトを使います。
import boto3
ec2 = boto3.resource('ec2')
instance = ec2.create_instances(
ImageId='ami-0c55b159cbfafe1f0',
MinCount=1,
MaxCount=1,
InstanceType='t2.micro',
KeyName='my-key-pair',
SecurityGroupIds=['sg-12345678']
)
print(f"Created Instance ID: {instance[0].id}")一般的には、細かい制御が必要な場面ではclient、直感的な操作を優先したい場面ではresourceを使い分けるケースが多いようです。
EC2運用を自動化する方法
EC2はAWSの主要なコンピューティングサービスであり、多くのシステムで稼働の中心を担っています。手動管理では見落としが発生しやすく、t2.microインスタンス1台の停止し忘れだけでも月額約3,000円、複数台では月数万円規模の無駄なコストにつながるケースがあります。
起動・停止・再起動の自動化
以下は、EC2インスタンスの起動・停止・再起動を自動化する基本スクリプトです。
import boto3
import time
def start_ec2_instance(instance_id):
ec2 = boto3.client('ec2')
response = ec2.start_instances(InstanceIds=[instance_id])
print(f"Starting EC2 instance {instance_id}")
return response
def stop_ec2_instance(instance_id):
ec2 = boto3.client('ec2')
response = ec2.stop_instances(InstanceIds=[instance_id])
print(f"Stopping EC2 instance {instance_id}")
return response
def reboot_ec2_instance(instance_id):
ec2 = boto3.client('ec2')
response = ec2.reboot_instances(InstanceIds=[instance_id])
print(f"Rebooting EC2 instance {instance_id}")
return response
if __name__ == "__main__":
instance_id = "i-1234567890abcdef0"
start_ec2_instance(instance_id)
time.sleep(30)
reboot_ec2_instance(instance_id)
time.sleep(30)
stop_ec2_instance(instance_id)ステータス確認用の関数も併せて用意しておくと、起動完了を待ってから次の処理に進むといった制御がしやすくなります。
def get_ec2_instance_status(instance_id):
ec2 = boto3.client('ec2')
response = ec2.describe_instances(InstanceIds=[instance_id])
status = response['Reservations'][0]['Instances'][0]['State']['Name']
print(f"EC2 instance {instance_id} status: {status}")
return statusステータスは pending、running、stopping、stopped、shutting-down、terminated の6種類で表現されます。定期的にこの状態をポーリングし、running状態に変わったタイミングでアラート送信や後続処理を発火させるといった構成がよく採用されています。
CloudWatchによる監視自動化
CloudWatchメトリクスを取得すれば、CPU使用率などをもとに自動で異常検知が行えます。以下はCPU使用率が80%を超えた場合にSNS通知を送るスクリプトです。
import boto3
from datetime import datetime, timedelta
def get_cpu_utilization(instance_id):
cloudwatch = boto3.client('cloudwatch')
response = cloudwatch.get_metric_statistics(
Namespace='AWS/EC2',
MetricName='CPUUtilization',
Dimensions=[{'Name': 'InstanceId', 'Value': instance_id}],
StartTime=datetime.utcnow() - timedelta(minutes=5),
EndTime=datetime.utcnow(),
Period=300,
Statistics=['Average']
)
datapoints = response['Datapoints']
if datapoints:
latest_cpu = max(datapoints, key=lambda x: x['Timestamp'])['Average']
print(f"Latest CPU Utilization: {latest_cpu}%")
return latest_cpu
return None
def check_cpu_threshold(instance_id, threshold=80):
cpu_utilization = get_cpu_utilization(instance_id)
if cpu_utilization and cpu_utilization > threshold:
sns = boto3.client('sns')
sns.publish(
TopicArn='arn:aws:sns:ap-northeast-1:123456789012:MyTopic',
Message=f"High CPU Utilization Alert: {cpu_utilization}%"
)CPUUtilization以外にも、DiskReadOps/DiskWriteOps(ディスク読み書き回数)、NetworkIn/NetworkOut(通信量)などのメトリクスが監視対象としてよく使われます。監視間隔を300秒(5分)に設定し、1日あたり288回のデータポイントを収集するのが標準的な構成とされています。
運用前チェックリスト
- □ IAMロールまたはIAMユーザーの権限範囲を確認したか
- □ 停止・再起動対象のインスタンスIDに誤りがないか
- □ CloudWatchアラームのしきい値(例:80%)が妥当か
- □ SNSトピックの通知先が正しく設定されているか
- □ AMIからの起動テストを本番投入前に1回は実施したか
AMIを使ったテンプレート起動
AMI(Amazon Machine Image)を活用すると、同じ構成のインスタンスを繰り返し複製できます。
import boto3
def launch_ec2_instance_from_ami(ami_id, instance_type='t2.micro', key_name=None,
security_group_ids=None, subnet_id=None,
min_count=1, max_count=1):
ec2 = boto3.client('ec2')
kwargs = {
'ImageId': ami_id,
'InstanceType': instance_type,
'MinCount': min_count,
'MaxCount': max_count,
}
if key_name:
kwargs['KeyName'] = key_name
if security_group_ids:
kwargs['SecurityGroupIds'] = security_group_ids
if subnet_id:
kwargs['SubnetId'] = subnet_id
response = ec2.run_instances(**kwargs)
instance_id = response['Instances'][0]['InstanceId']
print(f"Launched EC2 instance {instance_id} from AMI {ami_id}")
return instance_idAMIテンプレートを利用すると、環境構築にかかる作業時間を手動構築時の1/10程度まで圧縮できたという事例も見られます。
S3管理を効率化するには?
Amazon S3はオブジェクトストレージとしてバックアップやデータ保管に広く使われています。手動でのファイル操作は数十件程度なら耐えられますが、数百〜数千件のファイルを扱う運用では自動化が事実上必須になります。
アップロード・ダウンロード・削除
import boto3
import os
def upload_file_to_s3(bucket_name, file_path, object_name=None):
s3 = boto3.client('s3')
if object_name is None:
object_name = os.path.basename(file_path)
s3.upload_file(file_path, bucket_name, object_name)
print(f"Uploaded to s3://{bucket_name}/{object_name}")
return True
def download_file_from_s3(bucket_name, object_name, file_path=None):
s3 = boto3.client('s3')
if file_path is None:
file_path = os.path.basename(object_name)
s3.download_file(bucket_name, object_name, file_path)
print(f"Downloaded to {file_path}")
return True
def delete_file_from_s3(bucket_name, object_name):
s3 = boto3.client('s3')
s3.delete_object(Bucket=bucket_name, Key=object_name)
print(f"Deleted s3://{bucket_name}/{object_name}")
return True
def list_files_in_s3(bucket_name, prefix=''):
s3 = boto3.client('s3')
response = s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
if 'Contents' in response:
for obj in response['Contents']:
print(f"s3://{bucket_name}/{obj['Key']} ({obj['Size']} bytes)")
return responseS3標準ストレージの料金は1GBあたり月額2.71円前後(東京リージョン、2026年時点の目安)とされています。数百GB規模のデータを扱う運用では、削除漏れが積み重なるだけで月数千円単位のコスト増につながる可能性があります。
ライフサイクルルールの自動設定
import boto3
def set_s3_lifecycle_policy(bucket_name):
s3 = boto3.client('s3')
lifecycle_policy = {
'Rules': [
{
'ID': 'DeleteOldFiles',
'Status': 'Enabled',
'Filter': {'Prefix': ''},
'Expiration': {'Days': 30},
'NoncurrentVersionExpiration': {'NoncurrentDays': 7}
},
{
'ID': 'TransitionToIA',
'Status': 'Enabled',
'Filter': {'Prefix': 'logs/'},
'Transitions': [{'Days': 30, 'StorageClass': 'STANDARD_IA'}]
}
]
}
s3.put_bucket_lifecycle_configuration(
Bucket=bucket_name,
LifecycleConfiguration=lifecycle_policy
)
print(f"Lifecycle policy set for {bucket_name}")ログファイルを30日でIA(低頻度アクセス)ストレージへ移行し、さらに古いものを自動削除する構成にすると、ストレージコストを40%前後圧縮できたという報告があります。バージョニングを有効化している場合は、旧バージョンの保持期間(NoncurrentDays)を7日程度に設定しておくと、無駄な保管コストの発生を抑えやすくなります。
暗号化とセキュリティポリシー
S3バケットにはサーバーサイド暗号化(SSE-S3やSSE-KMS)を適用しておくのが基本構成です。put_bucket_encryption APIを使えば、暗号化設定もスクリプトから一括適用できます。バケットポリシーで「HTTPS以外のアクセスを拒否する」条件を仕込んでおくと、平文通信によるデータ漏洩の可能性を抑えられます。
Lambdaで定期実行する
EC2やS3の操作スクリプトは、Lambda関数として実装するとサーバーレスで定期実行できるようになります。EC2上にスクリプト実行用のサーバーを1台常時稼働させる必要がなくなるため、月額数百円〜千円規模のコスト削減につながるケースもあります。
Lambda関数はboto3を含むランタイム環境で動作し、CloudWatch Events(EventBridge)のルールと組み合わせることで「毎日1回、深夜2時にEC2を自動停止する」といったスケジュール実行が可能になります。AWS Lambdaには月100万回のリクエストまで無料枠が用意されており、日次バッチのような処理であれば実質0円で運用できるケースがほとんどです。
デプロイの流れは、Lambda関数用のZIPパッケージを作成し、boto3のcreate_functionメソッドでアップロードし、EventBridgeルールにターゲットとして紐づける、という3ステップです。稼働率はAWSのSLA上99.95%が目安とされており、業務時間外のEC2自動停止のような定型処理との相性が良いといえます。
IAM権限設計のコツ
自動化スクリプトを安全に運用するには、IAMユーザー・ロールの権限設計が土台になります。フルアクセス権限を一律に付与してしまうと、スクリプトの不具合や認証情報の漏洩が発生した際の被害範囲が広がってしまいます。
IAMユーザーの自動作成、カスタムポリシーの適用、EC2インスタンスロールの割り当てまでを一連のスクリプトにまとめておくと、新規プロジェクト立ち上げ時の権限設定作業を数十分から数分に短縮できます。ポリシーはリソースごとに個別のJSONで定義し、Action・Resource・Conditionの3要素で範囲を絞り込みます。たとえばEC2の起動・停止のみを許可し、削除やセキュリティグループの変更は許可しない、といった粒度での設計が可能です。
アクセスキーは90日ごとのローテーションを推奨する構成が一般的とされ、CloudWatchやLambdaと連携して期限切れ間近のキーを自動検知する仕組みを組み込んでいるケースも見られます。権限を必要最小限に絞ることで、仮に1つの認証情報が漏洩した場合でも、被害を全体の一部にとどめられる可能性が高まります。
セキュリティ対策とは?
自動化スクリプトの運用では、認証情報の管理と権限設計、そして操作ログの監査という3つの軸を押さえておくとリスクを抑えやすくなります。
| 対策項目 | 具体的な内容 | 推奨頻度・目安 |
|---|---|---|
| 認証情報管理 | 環境変数やSecrets Managerで管理し、コードに直書きしない | ローテーション90日ごと |
| 最小権限設計 | 必要なAction・Resourceのみを許可するポリシーを作成 | 四半期ごとに棚卸し |
| 操作ログ監査 | CloudTrailで全API呼び出しを記録し、異常アクセスを検知 | ログ保持90日以上 |
| アラート通知 | SNS連携でしきい値超過時に即時通知 | 常時稼働 |
CloudTrailを有効化しておくと、誰が・いつ・どのAPIを呼び出したかが年間数百万件規模で記録され、あとから操作履歴をたどれるようになります。漏洩したアクセスキーが不正利用された場合、被害額が数百万円規模に膨らむ事例も報告されており、認証情報の管理は運用フローの中に組み込んでおく価値があります。
よくあるエラーとしては、権限不足による「AccessDenied」、リージョン指定漏れによる「EndpointConnectionError」、リクエスト過多による「Throttling」などが挙げられます。Throttlingエラーは短時間に大量のAPIを呼び出した際に発生しやすく、リトライ処理にexponential backoff(指数関数的な待機時間の増加)を組み込むことで回避しやすくなるとされています。
よくある質問
Q1. boto3とAWS CLIはどちらを使うべきですか?
単発のコマンド実行ならAWS CLI、条件分岐やループを含む複雑な自動化処理を組みたい場合はboto3が向いているとされています。両者を併用する現場も少なくありません。
Q2. IAMロールとIAMユーザー、どちらを先に使い始めるべきですか?
EC2やLambda上でスクリプトを動かすならIAMロール、ローカル開発環境ではIAMユーザーという使い分けが一般的です。鍵管理の手間を考えると、クラウド上で完結する処理はロールに寄せるほうが運用負荷を抑えやすい傾向があります。
Q3. boto3のバージョンはどのくらいの頻度で更新すべきですか?
新サービスへの対応やセキュリティ修正が含まれることがあるため、月1回程度リリースノートを確認し、影響がないか確かめたうえで更新するという運用が見られます。
Q4. スクリプトの実行に失敗した場合、まず何を確認すればいいですか?
エラーメッセージに含まれるAPIレスポンスのエラーコードを確認し、AccessDenied(権限不足)、Throttling(呼び出し過多)、EndpointConnectionError(リージョン設定ミス)のいずれに該当するかを切り分けると原因特定が早まります。
Q5. 自動化スクリプトのテストはどのように行えばいいですか?
本番環境に反映する前に、検証用のAWSアカウントやサンドボックス環境で1〜2回動作確認を行い、想定通りの挙動になっているかを確かめる流れが推奨されています。moto(boto3のモックライブラリ)を使ったユニットテストを組み込む現場も増えています。
本記事はInfra Academy編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。 編集ポリシーはこちら




