Amazon Elastic Compute Cloud
Linux インスタンス用ユーザーガイド

Linux インスタンスでの起動時のコマンドの実行

Amazon EC2 でインスタンスを起動するとき、起動後にそのインスタンスにユーザーデータを渡し、一般的な自動設定タスクを実行したり、スクリプトを実行したりできます。2 つのタイプのユーザーデータを Amazon EC2 に渡すことができます。シェルスクリプトと cloud-init ディレクティブです。また、このデータはプレーンテキスト、ファイル (コマンドラインツールを使用してインスタンスを起動する場合に便利です)、または base64 でエンコードされたテキスト (API コールの場合) として、起動ウィザードに渡すこともできます。

より複雑なオートメーションのシナリオに興味がある場合、AWS CloudFormation や AWS OpsWorks のご利用を検討してください。詳細については、「AWS CloudFormation ユーザーガイド」および「AWS OpsWorks ユーザーガイド」を参照してください。

Windows インスタンスの起動時にコマンドを実行する方法については、『Windows インスタンスの Amazon EC2 ユーザーガイド』の「Windows インスタンスでの起動時のコマンドの実行」および「Windows インスタンス設定の管理」を参照してください。

次の例では、「Amazon Linux 2 に LAMP ウェブサーバーをインストールする」のコマンドが、シェルスクリプトと、インスタンスの起動時に実行される一連の cloud-init ディレクティブに変換されています。各例では、次のタスクがユーザーデータにより実行されます。

  • ディストリビューションソフトウェアパッケージが更新されます。

  • 必要なウェブサーバー、phpmariadb パッケージがインストールされます。

  • systemctl を介して httpd サービスが開始され、オンになります。

  • ec2-user が apache グループに追加されます。

  • ウェブディレクトリとその中に含まれるファイルに対して、適切な所有権とファイル権限が設定されます。

  • ウェブサーバーと PHP エンジンをテストするために、シンプルなウェブページが作成されます。

By default, user data scripts and cloud-init directives run only during the first boot cycle when an instance is launched. However, you can configure your user data scripts and cloud-init directives to run every time the instance is restarted from a stopped state. For more information, see How can I execute user data after the initial launch of my EC2 instance? in the AWS Knowledge Center.

前提条件

次の例では、インターネットからアクセス可能なパブリック DNS 名がお客様のインスタンスに設定されているものと仮定しています。詳細については、「ステップ 1: インスタンスを起動する」を参照してください。また、SSH (ポート 22)、HTTP (ポート 80)、HTTPS (ポート 443) 接続を許可するように、セキュリティグループを設定する必要もあります。前提条件の詳細については、Amazon EC2 でのセットアップ を参照してください。

また、これらの指示は Amazon Linux 2 での使用を意図しています。他の Linux ディストリビューションの場合、コマンドとディレクティブが動作しないことがあります。cloud-init のサポートなど、その他のディストリビューションについての詳細は、該当するディストリビューションの文書を参照してください。

ユーザーデータとシェルスクリプト

シェルスクリプトに詳しい場合、シェルスクリプトが起動時に指示を送る最も簡単で完全な方法となります。cloud-init 出力ログファイル (/var/log/cloud-init-output.log) にコンソール出力が記録されるので、インスタンスが意図したとおりに動作しない場合、起動後にスクリプトを簡単にデバッグできます。

重要

By default, user data scripts and cloud-init directives run only during the first boot cycle when an instance is launched. However, you can configure your user data scripts and cloud-init directives to run every time the instance is restarted from a stopped state. For more information, see How can I execute user data after the initial launch of my EC2 instance? in the AWS Knowledge Center.

ユーザーデータのシェルスクリプトは、#! の記号と、スクリプトを読み取るインタープリタのパス (通常は /bin/bash)) から始める必要があります。シェルスクリプトの概要については、Linux Documentation Project (tldp.org) の BASH Programming HOW-TO を参照してください。

ユーザーデータとして入力されたスクリプトは、root ユーザーとして実行されます。そのため、スクリプトでは sudo コマンドを使用しないでください。作成したファイルはすべてrootルートの所有になることを忘れないでください。非 ユーザーにファイルアクセスを与える場合、スクリプトで権限を適宜変更する必要があります。また、スクリプトはインタラクティブに実行されないため、ユーザーフィードバックを必要とするコマンド (-y フラグのない yum update など) を含めることはできません。

起動時にこれらのタスクを追加すると、インスタンスの起動にかかる時間が増えます。タスクが完了するまでさらに数分待ち、それからユーザースクリプトが正常に完了したことをテストしてください。

ユーザーデータおよびコンソール

インスタンスの起動時のインスタンスユーザーデータを指定できます。インスタンスのルートボリュームが EBS ボリュームの場合は、インスタンスを停止してユーザーデータを更新することもできます。

起動時にインスタンスユーザーデータを指定する

AMI からのインスタンスの起動 でインスタンスを起動するための手順を行いますが、その手順で ステップ 6 に到達したら、シェルスクリプトを [User data] フィールドにコピーして、起動手順を完了します。

下のスクリプト例では、スクリプトがウェブサーバーを作成し、設定します。

#!/bin/bash yum update -y amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2 yum install -y httpd mariadb-server systemctl start httpd systemctl enable httpd usermod -a -G apache ec2-user chown -R ec2-user:apache /var/www chmod 2775 /var/www find /var/www -type d -exec chmod 2775 {} \; find /var/www -type f -exec chmod 0664 {} \; echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

インスタンスが起動し、スクリプトのコマンドを実行するまで十分待ち、それからスクリプトが意図したタスクを完了したことを確認します。

例では、ウェブブラウザにスクリプトが作成した PHP テストファイルの URL を入力します。この URL は、インスタンスのパブリック DNS アドレスにスラッシュとファイル名を追加したものです。

http://my.public.dns.amazonaws.com/phpinfo.php

PHP 情報ページが表示されるはずです。PHP 情報ページが表示されない場合、使用しているセキュリティグループに HTTP (ポート 80) トラフィックを許可するルールが含まれていることを確認します。詳細については、「セキュリティグループへのルールの追加」を参照してください。

(オプション) スクリプトが予定のタスクを完了しなかった場合、あるいはスクリプトがエラーせずにタスクを完了したかを確認するには、/var/log/cloud-init-output.log にある cloud-init 出力ログファイルを調べ、エラーメッセージが出力されていないか探します。

デバッグの詳細情報を取得するには、次のディレクティブを指定して cloud-init データセクションを含む Mime マルチパートアーカイブを作成します。

output : { all : '| tee -a /var/log/cloud-init-output.log' }

このディレクティブにより、スクリプトから /var/log/cloud-init-output.log にコマンド出力が送信されます。cloud-init データ形式と MIME マルチパートアーカイブの作成方法の詳細については、「cloud-init Formats」を参照してください。

インスタンスユーザーデータの表示と更新

インスタンスユーザーデータを変更するには

  1. https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。

  2. ナビゲーションペインで、[インスタンス] を選択します。

  3. インスタンスを選択し、[Actions]、[Instance State]、[Stop] の順に選択します。

    警告

    インスタンスを停止すると、インスタンスストアボリューム上のデータは消去されます。したがって、インスタンスストアボリューム上に維持したいデータがある場合は、必ず永続的ストレージにバックアップしてください。

  4. 確認を求めるメッセージが表示されたら、[Yes, Stop] を選択します。インスタンスが停止するまで、数分かかる場合があります。

  5. インスタンスが選択された状態のまま、[Actions(アクション)] を選択し、[Instance Settings(インスタンス設定)] を選択して、[View/Change User Data(ユーザーデータの表示/変更)] を選択します。インスタンスの実行中はユーザーデータを変更できませんが、表示することはできます。

  6. [View/Change User Data] ダイアログボックスで、ユーザーデータを更新し、[Save] を選択します。

  7. インスタンスを再起動します。新しいユーザーデータは、再起動後にインスタンス上に表示されますが、ユーザーデータスクリプトは実行されません。

ユーザーデータと cloud-init ディレクティブ

cloud-init パッケージは、新しい Amazon Linux インスタンスが起動したときに、特定の側面を設定します。具体的には、お客様のプライベートキーでログインできるように、ec2-user の .ssh/authorized_keys ファイルを設定します。詳細については、「cloud-init」を参照してください。

構文は異なりますが、渡されたスクリプトと同じ方法で cloud-init ユーザーディレクティブを起動時のインスタンスに渡すことができます。cloud-init の詳細については、http://cloudinit.readthedocs.org/en/latest/index.html にアクセスしてください。

重要

By default, user data scripts and cloud-init directives run only during the first boot cycle when an instance is launched. However, you can configure your user data scripts and cloud-init directives to run every time the instance is restarted from a stopped state. For more information, see How can I execute user data after the initial launch of my EC2 instance? in the AWS Knowledge Center.

cloud-init の Amazon Linux バージョンは、ベースパッケージで利用できるディレクティブの一部をサポートしません。一部のディレクティブは名前が変更されています (たとえば、apt-upgrade の代わりに repo_update が使用されています)。

起動時にこれらのタスクを追加すると、インスタンスの起動にかかる時間が増えます。タスクが完了するまでさらに数分待ち、それからユーザーデータディレクティブが完了したことをテストしてください。

ユーザーデータで cloud-init ディレクティブをインスタンスに渡すには

  1. AMI からのインスタンスの起動 でインスタンスを起動するための手順を行いますが、その手順で ステップ 6 に到達したら、cloud-init ディレクティブテキストを [User data] フィールドに貼り付け、起動手順を完了します。

    下の例では、ディレクティブが Amazon Linux 2 でウェブサーバーを作成し、設定します。一番上の #cloud-config 行は、cloud-init ディレクティブとしてコマンドを識別するために必要です。

    #cloud-config repo_update: true repo_upgrade: all packages: - httpd - mariadb-server runcmd: - [ sh, -c, "amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2" ] - systemctl start httpd - sudo systemctl enable httpd - [ sh, -c, "usermod -a -G apache ec2-user" ] - [ sh, -c, "chown -R ec2-user:apache /var/www" ] - chmod 2775 /var/www - [ find, /var/www, -type, d, -exec, chmod, 2775, {}, \; ] - [ find, /var/www, -type, f, -exec, chmod, 0664, {}, \; ] - [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]
  2. インスタンスが起動し、ユーザーデータのディレクティブを実行するまで十分待ち、それから意図したタスクをディレクティブが完了したことを確認します。

    例では、ウェブブラウザにディレクティブが作成した PHP テストファイルの URL を入力します。この URL は、インスタンスのパブリック DNS アドレスにスラッシュとファイル名を追加したものです。

    http://my.public.dns.amazonaws.com/phpinfo.php

    PHP 情報ページが表示されるはずです。PHP 情報ページが表示されない場合、使用しているセキュリティグループに HTTP (ポート 80) トラフィックを許可するルールが含まれていることを確認します。詳細については、「セキュリティグループへのルールの追加」を参照してください。

  3. (オプション) ディレクティブが予定のタスクを完了しなかった場合、あるいはディレクティブがエラーなしでタスクを完了したかを確認するには、/var/log/cloud-init-output.log にある出力ログファイルを調べ、エラーメッセージが出力されていないか探します。デバッグの詳細情報を取得するには、ディレクティブに次の行を追加します:

    output : { all : '| tee -a /var/log/cloud-init-output.log' }

    このディレクティブにより、runcmd 出力が /var/log/cloud-init-output.log に送信されます。

ユーザーデータと AWS CLI

AWS CLI を使用して、インスタンスのユーザーデータを指定、変更、表示することができます。インスタンスのメタデータを使用して、インスタンスからユーザーデータを表示する方法については、「インスタンスユーザーデータを取得する」を参照してください。

Windows では、AWS CLI を使用する代わりに AWS Tools for Windows PowerShell を使用できます。詳細については、『Windows インスタンスの Amazon EC2 ユーザーガイド』の「ユーザーデータと Tools for Windows PowerShell」を参照してください。

例: ユーザーデータは、起動時に指定します。

インスタンスの起動時にユーザーデータを指定するには、run-instances コマンドと --user-data パラメータを使用します。run-instances で、AWS CLI はユーザーデータの base64 エンコードを実行します。

次の例は、コマンドラインで文字列としてスクリプトを指定する方法を示しています。

aws ec2 run-instances --image-id ami-abcd1234 --count 1 --instance-type m3.medium \ --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 \ --user-data echo user data

次の例は、テキストファイルを使用してスクリプトを指定する方法を示しています。ファイルを指定するには、必ず file:// プレフィックスを使用してください。

aws ec2 run-instances --image-id ami-abcd1234 --count 1 --instance-type m3.medium \ --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 \ --user-data file://my_script.txt

シェルスクリプトを使用したテキストファイルの例を次に示します。

#!/bin/bash yum update -y service httpd start chkconfig httpd on

例: 停止しているインスタンスのユーザーデータを変更します。

停止したインスタンスのユーザーデータは、modify-instance-attribute コマンドを使用して変更できます。modify-instance-attribute では、AWS CLI はユーザーデータの base64 エンコードを実行しません。

Linux では、base64 コマンドを使用してユーザーデータをエンコードします。

base64 my_script.txt >my_script_base64.txt

Windows では、certutil コマンドを使用してユーザーデータをエンコードします。このファイルを AWS CLI で使用する前に、最初の (証明書の開始) 行と最後の (証明書の終了) 行を削除する必要があります。

certutil -encode my_script.txt my_script_base64.txt notepad my_script_base64.txt

--attribute および --value パラメータを使用して、エンコードされたテキストファイルを使用してユーザーデータを指定します。ファイルを指定するには、必ず file:// プレフィックスを使用してください。

aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --value file://my_script_base64.txt

例: ユーザーデータの表示

インスタンスのユーザーデータを取得するには、describe-instance-attribute コマンドを使用します。describe-instance-attribute では、AWS CLI はユーザーデータの base64 デコードを実行しません。

aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData

ユーザーデータが base64 でエンコードされた出力例を次に示します。

{ "UserData": { "Value": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQpzZXJ2aWNlIGh0dHBkIHN0YXJ0CmNoa2NvbmZpZyBodHRwZCBvbg==" }, "InstanceId": "i-1234567890abcdef0" }

Linux では、--query オプションを使用してエンコードされたユーザーデータを取得し、base64 コマンドを使用してデコードします。

aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" | base64 --decode

Windows では、--query オプションを使用してコード化されたユーザーデータを取得し、certutil コマンドを使用してコードをデコードします。エンコードされた出力はファイルに保存され、デコードされた出力は別のファイルに保存されることに注意してください。

aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" >my_output.txt certutil -decode my_output.txt my_output_decoded.txt type my_output_decoded.txt

出力例を次に示します。

#!/bin/bash yum update -y service httpd start chkconfig httpd on