當您使用使用者資料輸入啟動 EC2 執行個體時執行命令 - Amazon Elastic Compute Cloud

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

當您使用使用者資料輸入啟動 EC2 執行個體時執行命令

啟動 Amazon EC2 執行個體時,您可以將使用者資料傳遞至用來執行自動組態任務的執行個體,或在執行個體啟動後執行指令碼。

如果您對更複雜的自動化案例感興趣,可以考慮 AWS CloudFormation。如需詳細資訊,請參閱 AWS CloudFormation 使用者指南中的使用 在 Amazon EC2 上部署應用程式 AWS CloudFormation

在 Linux 執行個體上,您可以將兩種類型的使用者資料傳遞至 Amazon EC2: shell 指令碼和 Cloud-init 指令。您也可以將此資料以純文字、檔案 (這對於使用命令列工具啟動執行個體很有用) 或 base64 編碼的文字 (針對 API 呼叫) 傳遞至啟動執行個體精靈。

在 Windows 執行個體上,啟動代理程式會處理您的使用者資料指令碼。下列各節說明使用者資料在各作業系統上的處理方式差異。

中的使用者資料 AWS Management Console

您可以在啟動執行個體時指定執行個體使用者資料。如果執行個體的根磁碟區是 EBS 磁碟區,您也可以停止執行個體並更新其使用者資料。

使用啟動精靈在啟動時指定執行個體使用者資料

您可以在 EC2 主控台中使用啟動精靈啟動執行個體時指定使用者資料。若要在啟動時指定使用者資料,請遵循啟動執行個體的程序。此 User data (使用者資料) 欄位位於啟動執行個體精靈的 進階詳細資訊 區段中。在使用者資料欄位中輸入您的 PowerShell 指令碼,然後完成執行個體啟動程序。

在以下使用者資料欄位的螢幕擷取畫面中,範例指令碼會在 Windows 暫時資料夾中建立一個檔案,並在檔名中使用目前日期和時間。當您包括 <persist>true</persist> 時,指令碼會在您每次重新開機或啟動執行個體時執行。如果您將使用者資料保留為 base64 編碼核取方塊空白,Amazon EC2 主控台會為您執行 base64 編碼。

Advanced Details (進階詳細資訊) 使用者資料文字欄位。

如需詳細資訊,請參閱使用啟動精靈在啟動時指定執行個體使用者資料。如需使用 的 Linux 範例 AWS CLI,請參閱 使用者資料和 AWS CLI。如需使用 Tools for Windows PowerShell 的 Windows 範例,請參閱 使用者資料和適用於 Windows PowerShell 的工具

檢視及更新執行個體使用者資料

您可以檢視任何執行個體的執行個體使用者資料,並更新已終止之執行個體的執行個體使用者資料。

使用主控台更新執行個體的使用者資料
  1. 在 EC2 開啟 Amazon https://console.aws.amazon.com/ec2/ 主控台。

  2. 在導覽窗格中,選擇 Instances (執行個體)。

  3. 選取執行個體,並選取 Actions (動作)Instance state (執行個體狀態)Stop instance (停止執行個體)

    警告

    停止執行個體時,在任何執行個體存放區磁碟區的資料都會清除。若要保留執行個體存放區磁碟區的資料,請將資料備份至持久性儲存。

  4. 出現確認提示時,請選擇 Stop (停止)。停止執行個體可能需要幾分鐘。

  5. 在仍然選取執行個體的情況下,選取動作 > 執行個體設定 > 編輯使用者資料。您無法在執行個體仍在執行中時變更使用者資料,但您可以檢視它。

  6. Edit user data (編輯使用者資料) 對話方塊中,更新使用者資料,然後選擇 Save (儲存)。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼,請新增 <persist>true</persist>,如下範例所示:

    Edit User Data (編輯使用者資料) 對話方塊。
  7. 啟動實例。若您已為後續的重新開機或啟動啟用使用者資料執行,即會在執行個體啟動程序期間執行更新的使用者資料指令碼。

Amazon EC2 如何處理 Linux 執行個體的使用者資料

在下列範例中,在 Amazon Linux 2 上安裝 LAMP 伺服器中的命令會轉換為 Shell 指令碼,以及一組在執行個體啟動時執行的 Cloud-init 指令。在每個範例中,以下任務都會由使用者資料執行:

  • 更新分佈軟體套件。

  • 安裝必要 Web 伺服器、phpmariadb 套件。

  • 透過 systemctl 啟動並開啟 httpd 服務。

  • ec2-user 即會新增至 apache 群組。

  • 接著便會為 Web 目錄和其中包含的檔案設定適當的所有權和檔案許可。

  • 會建立簡單的網頁來測試 Web 伺服器和 PHP 引擎。

必要條件

此主題中的範例假設如下內容:

  • 您的執行個體具有可從網際網路存取的公有 DNS 名稱。

  • 與執行個體相關聯的安全群組設定為允許 SSH (連接埠 22) 流量,以便您可以連線至執行個體以檢視輸出日誌檔案。

  • 您的執行個體會使用 Amazon Linux 2 AMI 啟動。這些說明適用於與 Amazon Linux 2 搭配使用的情況,因此命令和指示詞可能無法在其他 Linux 發行版本上運作。如需其他分佈的詳細資訊,例如支援 cloud-init 的情形,請參閱其特定文件。

使用者資料與 Shell 指令碼

如果您熟悉 Shell 指令碼,這是在啟動時將指令傳送至執行個體的最簡單且最完整的方式。在開機階段新增這些任務也會增加開機執行個體所需要的時間長度。任務完成需要多花幾分鐘的時間,接著您便可以測試使用者指令碼是否已成功完成。

重要

依預設,使用者資料指令碼和 cloud-init 指令只會在您第一次啟動執行個體時的開機週期過程中執行。您可以更新設定,以確保每次重新啟動執行個體時,您的使用者資料指令碼和 cloud-init 指令都會執行。如需詳細資訊,請參閱 AWS 知識中心中的如何利用使用者資料在每次重新啟動 Amazon EC2 Linux 執行個體時自動執行指令碼?

使用者資料 shell 指令碼必須以 #! 字元,以及您希望讀取指令碼 (通常是 /bin/bash)) 的解譯器路徑做為開頭。如需 Shell 指令碼的簡介,請參閱 GNU 作業系統網站上的 Bash 參考手冊

做為使用者資料輸入的指令碼會以根使用者的身分執行,因此請不要在指令碼中使用 sudo 命令。請記得,您建立的任何檔案都會由根使用者擁有;若您需要讓非超級使用者擁有檔案存取權,建議您根據需求在指令碼中修改許可。此外,因為指令碼不會以互動方式執行,您無法包含需要使用者意見回饋的命令 (例如不帶有 -y 標記的 yum update)。

如果您在使用者資料指令碼中使用 AWS API,包括 AWS CLI,則必須在啟動執行個體時使用執行個體設定檔。執行個體設定檔提供使用者資料指令碼發出 API 呼叫所需的適當 AWS 憑證。如需詳細資訊,請參閱 IAM 使用者指南中的使用執行個體設定檔。您指派給 IAM 角色的許可取決於您使用 API 呼叫的服務。如需詳細資訊,請參閱Amazon IAM 的 EC2 角色

cloud-init 輸出日誌檔案會擷取主控台輸出,因此,若執行個體在啟動後未以您想要的方式運作,則可輕鬆地對您的指令碼進行除錯。若要檢視日誌檔案,連線到執行個體並開啟 /var/log/cloud-init-output.log

處理使用者資料指令碼時,會將其複製到 /var/lib/cloud/instances/instance-id/ 並從中執行。在執行指令碼之後,不會將其刪除。從執行個體建立 AMI /var/lib/cloud/instances/instance-id/之前,請務必從 刪除使用者資料指令碼。否則,指令碼將存在於此目錄中從 AMI 啟動的任何執行個體上。

更新執行個體使用者資料

若要更新執行個體使用者資料,您必須先停止執行個體。如果執行個體正在執行,您可以檢視使用者資料,但無法進行修改。

警告

停止執行個體時,在任何執行個體存放區磁碟區的資料都會清除。若要保留執行個體存放區磁碟區的資料,請將資料備份至持久性儲存。

修改執行個體使用者資料
  1. 在 EC2 開啟 Amazon https://console.aws.amazon.com/ec2/ 主控台。

  2. 在導覽窗格中,選擇 Instances (執行個體)。

  3. 選取執行個體,並選取 Instance state (執行個體狀態)Stop instance (停止執行個體)。如果此選項已停用,則執行個體已停止或其根設備是執行個體存放磁碟區。

  4. 出現確認提示時,請選擇 Stop (停止)。停止執行個體可能需要幾分鐘。

  5. 在仍然選取執行個體的情況下,選取動作 > 執行個體設定 > 編輯使用者資料

  6. 視需要修改使用者資料,然後選擇儲存

  7. 啟動實例。新的使用者資料便會在執行個體啟動之後出現在執行個體上;但不會執行使用者資料指令碼。

使用者資料與 cloud-init 指示詞

cloud-init 套件會在啟動時設定新 Amazon Linux 執行個體的特定部分;最明顯的是,它會設定 ec2-user 的 .ssh/authorized_keys 檔案,讓您可以使用自己的私有金鑰登入。如需有關 cloud-init 套件針對 Amazon Linux 執行個體執行組態任務的詳細資訊,請參閱 Amazon Linux 2 使用者指南中的在 Amazon Linux 2 上使用 cloud-init

cloud-init 使用者指示詞可在啟動時,以傳遞指令碼相同的方式傳遞到執行個體,雖然語法不同。如需有關 cloud-init 的詳細資訊,請參閱 http://cloudinit.readthedocs.org/en/latest/index.html

重要

依預設,使用者資料指令碼和 cloud-init 指令只會在您第一次啟動執行個體時的開機週期過程中執行。您可以更新設定,以確保每次重新啟動執行個體時,您的使用者資料指令碼和 cloud-init 指令都會執行。如需詳細資訊,請參閱 AWS 知識中心中的如何利用使用者資料在每次重新啟動 Amazon EC2 Linux 執行個體時自動執行指令碼?

在開機階段新增這些任務也會增加開機執行個體所需要的時間長度。任務完成需要多花幾分鐘的時間,接著您便可以測試您的使用者資料指示詞是否已完成。

使用使用者資料將 cloud-init 指示詞傳遞給執行個體
  1. 請遵循啟動執行個體的程序。此 User data (使用者資料) 欄位位於啟動執行個體精靈的 進階詳細資訊 區段中。在 User data (使用者資料) 欄位中輸入您的 cloud-init 指示詞文字,然後完成執行個體啟動程序。

    在以下範例中,指示詞會在 Amazon Linux 2 上建立及設定 Web 伺服器。頂端的 #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. 給予執行個體充分的時間啟動及執行您使用者資料中的指示詞,然後檢查您的指示詞是否已完成您預計執行的任務。

    在此範例中,在 Web 瀏覽器中輸入指令建立的 URL 測試檔案的 PHP。此 URL 是執行個體的公有 DNS 地址,後面接著正斜線和檔案名稱。

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

    您應該會看到 PHP 資訊頁面。如果您看不到 PHP 資訊頁面,請檢查您使用的安全群組是否包含允許 HTTP (連接埠 80) 流量的規則。如需詳細資訊,請參閱設定安全群組規則

  3. (選用) 若您的指令並未完成您預期執行的任務,或您只希望確認您的指令已順利完成,而沒有發生任何錯誤,請連線到執行個體,檢查 cloud-init 輸出日誌檔案 (/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 來指定、修改和檢視執行個體的使用者資料。如需使用執行個體中繼資料檢視您執行個體中使用者資料的資訊,請參閱存取執行個體的EC2執行個體中繼資料

在 Windows 上,您可以使用 , AWS Tools for Windows PowerShell 而不是使用 AWS CLI。如需詳細資訊,請參閱 使用者資料和適用於 Windows PowerShell 的工具

範例:在啟動時指定使用者資料

若要在啟動您的執行個體時指定使用者資料,請搭配 --user-data 參數使用 run-instances 命令。透過 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

以下是具有 shell 指令碼的範例文字檔案。

#!/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 命令編碼使用者資料。您必須先移除第一個 (BEGINCERTIFICATE) 和最後一個 (CERTIFICATE) 行 AWS CLI,才能將此檔案與END 搭配使用。

    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
範例:清除已停止執行個體的使用者資料

若要刪除現有的使用者資料,請使用 modify-instance-attribute 命令,如下所示:

aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --user-data Value=
範例:檢視使用者資料

若要擷取執行個體的使用者資料,請使用 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

結合 shell 指令碼與 cloud-init 指令

根據預設,您一次只能在使用者資料中包含一種內容類型。不過,您可以使用 MIME 多部分檔案中的 text/cloud-configtext/x-shellscript 內容類型,以在使用者資料中包含 shell 指令碼和 cloud-init 指令。

以下展示 MIME 多部分格式。

Content-Type: multipart/mixed; boundary="//" MIME-Version: 1.0 --// Content-Type: text/cloud-config; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="cloud-config.txt" #cloud-config cloud-init directives --// Content-Type: text/x-shellscript; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="userdata.txt" #!/bin/bash shell script commands --//--

例如,下列使用者資料包含 cloud-init 指令和 bash shell 指令碼。cloud-init 指令會建立檔案 (/test-cloudinit/cloud-init.txt),並將 Created by cloud-init 寫入到該檔案。bash shell 指令碼會建立檔案 (/test-userscript/userscript.txt) 並將 Created by bash shell script 寫入到該檔案。

Content-Type: multipart/mixed; boundary="//" MIME-Version: 1.0 --// Content-Type: text/cloud-config; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="cloud-config.txt" #cloud-config runcmd: - [ mkdir, /test-cloudinit ] write_files: - path: /test-cloudinit/cloud-init.txt content: Created by cloud-init --// Content-Type: text/x-shellscript; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="userdata.txt" #!/bin/bash mkdir test-userscript touch /test-userscript/userscript.txt echo "Created by bash shell script" >> /test-userscript/userscript.txt --//--

Amazon EC2 如何處理 Windows 執行個體的使用者資料

在 Windows 執行個體上,啟動代理程式會執行與使用者資料相關的任務。如需詳細資訊,請參閱下列內容:

如需 AWS CloudFormation 範本中UserData屬性組合的範例,請參閱 Base64 Encoded UserData 屬性Base64 Encoded UserData 屬性 with AccessKey and SecretKey

如需在 Auto Scaling 群組內使用生命週期掛鉤的執行個體上執行命令的範例,請參閱 Amazon EC2 Auto Scaling 使用者指南中的教學課程:設定使用者資料以透過執行個體中繼資料擷取目標生命週期狀態

使用者資料指令碼

若要讓 EC2ConfigEC2Launch執行指令碼,您必須在將指令碼新增至使用者資料時,將指令碼括在特殊標籤內。您使用的標籤取決於命令是在命令提示視窗中執行 (批次命令) 或使用 Windows PowerShell。

如果您同時指定批次指令碼和 Windows PowerShell 指令碼,則批次指令碼會先執行,然後執行 Windows PowerShell 指令碼,無論它們在執行個體使用者資料中顯示的順序為何。

如果您在使用者資料指令碼中使用 AWS API AWS CLI,包括 ,則必須在啟動執行個體時使用執行個體設定檔。執行個體設定檔提供使用者資料指令碼進行 API 呼叫所需的適當 AWS 憑證。如需詳細資訊,請參閱執行個體描述檔。您指派給 IAM 角色的許可取決於您使用 API 呼叫的服務。如需詳細資訊,請參閱Amazon IAM 的 EC2 角色

批次指令碼的語法

使用 script 標籤指定批次指令碼。使用換行符號分隔命令,如下列範例所示。

<script> echo Current date and time >> %SystemRoot%\Temp\test.log echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log </script>

在預設情況下,使用者資料指令碼僅會在您啟動執行個體時執行一次。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼,請將 <persist>true</persist> 新增至使用者資料。

<script> echo Current date and time >> %SystemRoot%\Temp\test.log echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log </script> <persist>true</persist>
EC2Launch v2 代理程式

若要使用UserData階段中的 XML v2 executeScript任務執行 EC2Launch 使用者資料指令碼作為分離程序,請<detach>true</detach>新增至使用者資料。

注意

所以此 detach 標籤不受先前的啟動代理程式支援。

<script> echo Current date and time >> %SystemRoot%\Temp\test.log echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log </script> <detach>true</detach>

Windows PowerShell 指令碼的語法

AWS Windows AMIs 包含 AWS Tools for Windows PowerShell,因此您可以在使用者資料中指定這些 cmdlet。如果您將 IAM 角色與執行個體建立關聯,則不需要指定 cmdlet 的憑證,因為在執行個體上執行的應用程式會使用角色的憑證來存取 AWS 資源 (例如 Amazon S3 儲存貯體)。

使用 <powershell>標籤指定 Windows PowerShell 指令碼。使用分行符號來區隔命令。<powershell> 標籤區分大小寫。

例如:

<powershell> $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file </powershell>

根據預設,使用者資料指令碼會在您啟動執行個體時執行一次。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼,請將 <persist>true</persist> 新增至使用者資料。

<powershell> $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file </powershell> <persist>true</persist>

您可以使用 <powershellArguments>標籤指定一或多個 PowerShell 引數。如果未傳遞任何引數,則 EC2Launch 和 EC2Launch v2 預設會新增下列引數:-ExecutionPolicy Unrestricted

範例:

<powershell> $file = $env:SystemRoot + "\Temp" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file </powershell> <powershellArguments>-ExecutionPolicy Unrestricted -NoProfile -NonInteractive</powershellArguments>
EC2Launch v2 代理程式

若要使用UserData階段中的 XML v2 executeScript任務執行 EC2Launch 使用者資料指令碼作為分離程序,請<detach>true</detach>新增至使用者資料。

注意

所以此 detach 標籤不受先前的啟動代理程式支援。

<powershell> $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file </powershell> <detach>true</detach>

YAML 組態指令碼的語法

如果您使用 EC2Launch v2 執行指令碼,您可以使用 YAML 格式。若要檢視 EC2Launch v2 的組態任務、詳細資訊和範例,請參閱 EC2Launch v2 任務組態

使用executeScript任務指定 YAML 指令碼。

執行 a PowerShell 指令碼的 YAML 語法範例

version: 1.0 tasks: - task: executeScript inputs: - frequency: always type: powershell runAs: localSystem content: |- $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file

執行批次指令碼的 YAML 語法範例

version: 1.1 tasks: - task: executeScript inputs: - frequency: always type: batch runAs: localSystem content: |- echo Current date and time >> %SystemRoot%\Temp\test.log echo %DATE% %TIME% >> %SystemRoot%\Temp\test.log

Base64 編碼

如果您使用的是 Amazon EC2 API執行 base64 編碼使用者資料的工具,您必須自行編碼使用者資料。若否,系統就會記錄一則錯誤,指出找不到要執行的 scriptpowershell 標籤。以下是使用 Windows PowerShell 編碼的範例。

$UserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Script))

以下是使用 PowerShell 解碼的範例。

$Script = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($UserData))

如需 base64 編碼的詳細資訊,請參閱 https://www.ietf.org/rfc/rfc4648.txt

使用者資料執行

根據預設,所有 AWS Windows AMIs 都會啟用使用者資料執行以進行初始啟動。您可以指定在下一次重新開機或重新啟動執行個體時執行使用者資料指令碼。或者,您可以指定每次重新開機或重新啟動執行個體時都執行使用者資料指令碼。

注意

在預設情況下,初始啟動後不會執行使用者資料。若要在重新開機或啟動執行個體後執行使用者資料,請參閱 在後續重新啟動或啟動期間執行指令碼

產生隨機密碼時,會透過本機管理員帳戶來執行使用者資料指令碼。否則,會透過系統帳戶執行使用者資料指令碼。

執行個體啟動指令碼

執行個體使用者資料中的指令碼僅會在執行個體初次啟動時執行。如果找到 persist 標籤,即會為後續的重新開機或啟動啟用使用者資料執行。EC2Launch v2、EC2Launch 和 EC2Config 的日誌檔案包含標準輸出和標準錯誤串流的輸出。

EC2Launch v2

EC2Launch v2 的日誌檔案為 C:\ProgramData\Amazon\EC2Launch\log\agent.log

注意

C:\ProgramData 資料夾可能隱藏不見。若要檢視此資料夾,您必須顯示隱藏的檔案和資料夾。

以下資訊會在執行使用者資料時記錄:

  • Info: Converting user-data to yaml format – 如果使用者資料是以 XML 格式提供

  • Info: Initialize user-data state - 開始執行使用者資料時

  • Info: Frequency is: always - 如果使用者資料工作在每次開機時執行

  • Info: Frequency is: once - 如果使用者資料任務只執行一次

  • Stage: postReadyUserData execution completed - 使用者資料執行結束時

EC2Launch

EC2Launch 的記錄檔是 C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserdataExecution.log

C:\ProgramData 資料夾可能隱藏不見。若要檢視此資料夾,您必須顯示隱藏的檔案和資料夾。

以下資訊會在執行使用者資料時記錄:

  • Userdata execution begins - 開始執行使用者資料時

  • <persist> tag was provided: true - 如果找到 persist 標籤

  • Running userdata on every boot - 如果找到 persist 標籤

  • <powershell> tag was provided.. running powershell content - 如果找到 powershell 標籤

  • <script> tag was provided.. running script content - 如果找到指令碼標籤

  • Message: The output from user scripts - 如果執行使用者資料指令碼,則會記錄其輸出

EC2Config

EC2Config 的記錄檔是 C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2Config.log。以下資訊會在執行使用者資料時記錄:

  • Ec2HandleUserData: Message: Start running user scripts - 開始執行使用者資料時

  • Ec2HandleUserData: Message: Re-enabled userdata execution - 如果找到 persist 標籤

  • Ec2HandleUserData: Message: Could not find <persist> and </persist> - 如果沒有找到 persist 標籤

  • Ec2HandleUserData: Message: The output from user scripts - 如果執行使用者資料指令碼,則會記錄其輸出

在後續重新啟動或啟動期間執行指令碼

當您更新執行個體使用者資料時,使用者資料指令碼並未在您重新開機或啟動執行個體時自動執行。不過,您可以啟用使用者資料執行,以讓使用者資料指令碼在您重新開機或啟動執行個體時執行一次,或每次重新開機或啟動執行個體時都執行。

如果您選擇 Shutdown with Sysprep (使用 Sysprep 關機) 選項,使用者資料指令碼會在下次執行個體啟動或重新開機時執行,即使您並沒有為後續的重新開機或啟動啟用使用者資料執行亦同。使用者資料指令碼將不會在後續的重新開機或啟動時執行。

使用 EC2Launch v2 啟用使用者資料執行
  • 若要在第一次開機時在使用者資料中執行工作,請將 frequency 設定為 once

  • 若要在每次開機時在使用者資料中執行工作,請將 frequency 設定為 always

使用 EC2Launch 啟用使用者資料執行
  1. 連接至 Windows 執行個體。

  2. 開啟 a PowerShell 命令視窗並執行下列命令:

    C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
  3. 中斷連線您的 Windows 執行個體。若要在下一次啟動執行個體時執行更新的指令碼,請停止執行個體並更新使用者資料。

使用 EC2Config 啟用使用者資料執行
  1. 連接至 Windows 執行個體。

  2. Open C:\Program Files\Amazon\Ec2ConfigService\Ec2ConfigServiceSetting.exe.

  3. 針對使用者資料,選取 Enable UserData 執行以進行下一個服務啟動

  4. 中斷連線您的 Windows 執行個體。若要在下一次啟動執行個體時執行更新的指令碼,請停止執行個體並更新使用者資料。

使用者資料和適用於 Windows PowerShell 的工具

您可以使用 Tools for Windows PowerShell 來指定、修改和檢視執行個體的使用者資料。如需使用執行個體中繼資料檢視您執行個體中使用者資料的資訊,請參閱存取執行個體的EC2執行個體中繼資料。如需有關使用者資料和 的資訊 AWS CLI,請參閱 使用者資料和 AWS CLI

範例:在啟動時指定執行個體使用者資料

使用執行個體使用者資料建立文字檔案。若要在每次重新開機或啟動執行個體時執行使用者資料指令碼,請新增 <persist>true</persist>,如下範例所示。

<powershell> $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file </powershell> <persist>true</persist>

若要在啟動執行個體時指定執行個體使用者資料,請使用 New-EC2Instance 命令。此命令不會為您執行使用者資料的 base64 編碼。使用以下命令,將使用者資料編碼至名為 script.txt 的文字檔案:

PS C:\> $Script = Get-Content -Raw script.txt PS C:\> $UserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($Script))

使用 -UserData 參數,將使用者資料傳遞到 New-EC2Instance 命令。

PS C:\> New-EC2Instance -ImageId ami-abcd1234 -MinCount 1 -MaxCount 1 -InstanceType m3.medium \ -KeyName my-key-pair -SubnetId subnet-12345678 -SecurityGroupIds sg-1a2b3c4d \ -UserData $UserData
範例:更新已停止之執行個體的執行個體使用者資料

您可以使用 Edit-EC2InstanceAttribute 命令修改已停止執行個體的使用者資料。

使用新的指令碼建立文字檔案。使用以下命令,將使用者資料編碼至名為 new-script.txt 的文字檔案:

PS C:\> $NewScript = Get-Content -Raw new-script.txt PS C:\> $NewUserData = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($NewScript))

使用 -UserData-Value 參數指定使用者資料。

PS C:\> Edit-EC2InstanceAttribute -InstanceId i-1234567890abcdef0 -Attribute userData -Value $NewUserData
範例:檢視執行個體使用者資料

若要擷取執行個體的使用者資料,請使用 Get-EC2InstanceAttribute 命令。

PS C:\> (Get-EC2InstanceAttribute -InstanceId i-1234567890abcdef0 -Attribute userData).UserData

下列為範例輸出。請注意使用者資料已編碼。

PHBvd2Vyc2hlbGw+DQpSZW5hbWUtQ29tcHV0ZXIgLU5ld05hbWUgdXNlci1kYXRhLXRlc3QNCjwvcG93ZXJzaGVsbD4=

使用以下命令,將已編碼的使用者資料存放至變數中,然後加以解碼。

PS C:\> $UserData_encoded = (Get-EC2InstanceAttribute -InstanceId i-1234567890abcdef0 -Attribute userData).UserData PS C:\> [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($UserData_encoded))

下列為範例輸出。

<powershell> $file = $env:SystemRoot + "\Temp\" + (Get-Date).ToString("MM-dd-yy-hh-mm") New-Item $file -ItemType file </powershell> <persist>true</persist>
範例:重新命名執行個體以符合標籤值

您可以使用 Get-EC2Tag 命令來讀取標籤值、在第一次開機時重新命名執行個體以符合標籤值,以及重新啟動。若要成功執行此命令,您必須具有連接至執行個體的ec2:DescribeTags許可角色,因為 API 呼叫會擷取標籤資訊。如需使用 IAM 角色設定許可的詳細資訊,請參閱 將 IAM 角色連接至執行個體

IMDSv2
<powershell> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri 'http://169.254.169.254/latest/api/token' -UseBasicParsing $instanceId = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri 'http://169.254.169.254/latest/meta-data/instance-id' -UseBasicParsing $nameValue = (Get-EC2Tag -Filter @{Name="resource-id";Value=$instanceid},@{Name="key";Value="Name"}).Value $pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$" #Verify Name Value satisfies best practices for Windows hostnames If ($nameValue -match $pattern) {Try {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} Catch {$ErrorMessage = $_.Exception.Message Write-Output "Rename failed: $ErrorMessage"}} Else {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"} </powershell>
IMDSv1
<powershell> $instanceId = (Invoke-WebRequest http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).content $nameValue = (Get-EC2Tag -Filter @{Name="resource-id";Value=$instanceid},@{Name="key";Value="Name"}).Value $pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$" #Verify Name Value satisfies best practices for Windows hostnames If ($nameValue -match $pattern) {Try {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} Catch {$ErrorMessage = $_.Exception.Message Write-Output "Rename failed: $ErrorMessage"}} Else {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"} </powershell>

如果您的執行個體設定為從執行個體中繼資料存取標籤,則還可以使用執行個體中繼資料中的標籤重新命名執行個體,。如需詳細資訊,請參閱使用執行個體中繼資料檢視 EC2 執行個體的標籤

IMDSv2
<powershell> [string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri 'http://169.254.169.254/latest/api/token' -UseBasicParsing $nameValue = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri 'http://169.254.169.254/latest/meta-data/tags/instance/Name' -UseBasicParsing $pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$" #Verify Name Value satisfies best practices for Windows hostnames If ($nameValue -match $pattern) {Try {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} Catch {$ErrorMessage = $_.Exception.Message Write-Output "Rename failed: $ErrorMessage"}} Else {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"} </powershell>
IMDSv1
<powershell> $nameValue = Get-EC2InstanceMetadata -Path /tags/instance/Name $pattern = "^(?![0-9]{1,15}$)[a-zA-Z0-9-]{1,15}$" #Verify Name Value satisfies best practices for Windows hostnames If ($nameValue -match $pattern) {Try {Rename-Computer -NewName $nameValue -Restart -ErrorAction Stop} Catch {$ErrorMessage = $_.Exception.Message Write-Output "Rename failed: $ErrorMessage"}} Else {Throw "Provided name not a valid hostname. Please ensure Name value is between 1 and 15 characters in length and contains only alphanumeric or hyphen characters"} </powershell>