0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go AWS SDKを使用してEC2インスタンスにコマンドを実行する

Posted at

はじめに

GoのAWS SDKを使用してAWSのEC2インスタンスにコマンドを送信し、その結果を取得してみました。sshで接続してからのコマンド実行ではなく、AWS Systems Manager (SSM)の機能を使用してEC2インスタンスにコマンドを実行させました。

前提条件

  • SSM Agentのインストール: EC2インスタンスにSSM Agentがインストールされている必要があります。これにより、EC2のインスタンスがAWS Systems Managerと通信できるようになります。多くのAWS提供のAMIにはSSM Agentが事前にインストールされています。また、今回やりませんでしたが、手動でインストールすることもできます

  • 権限の設定: コマンドを実行するためには、IAMロールやポリシーを設定し、必要な権限を付与する必要があります。例えば、EC2インスタンスには、AmazonSSMManagedInstanceCoreポリシーをアタッチしたIAMロールを設定することでSSMからEC2に対してコマンド実行できるようになります

EC2インスタンスをSystems Managerのマネージドインスタンスとして登録(権限の設定)

今回は、Systems Managerの「高速セットアップ」機能を使用し、Default Host Management Configuration (DHMC)を設定しました。これにより、対象のEC2インスタンスに自動的にAmazonSSMManagedEC2InstanceDefaultPolicyが適用され、Systems Managerのマネージドインスタンスとして登録されます。この場合でも、SSMからEC2に対してコマンドを実行できるようになります。

以下は、DHMC設定時のキャプチャです。

  • Host Managementの設定
    image.png

  • 登録した結果を確認
    image.png

作成したコードについて

GoのAWS SDKを使用してEC2インスタンスでコマンドを実行するコードです。SSMの機能を使用してEC2に対してコマンドを実行します。

コマンド実行

package main

import (
	"fmt"
	"log"
 	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ssm"
)

// 中間のコードを省略

	// 1.AWSセッションの作成
	sess, err := session.NewSessionWithOptions(session.Options{
		Config: aws.Config{
			Region: aws.String("ap-northeast-1"), // 適切なリージョンを指定
		},
		Profile: "default", // 適切なプロファイルを指定
	})
	if err != nil {
		log.Fatalf("Failed to create session: %v", err)
	}

    // 2. SSMクライアントの作成  
	ssmClient := ssm.New(sess)

    // 3. コマンドの設定と送信
	instanceId := "your-instance-id" // EC2インスタンスIDを指定
	cmdstring := "echo Hello, World!" // 実行したいコマンドを指定
	output, err := ssmClient.SendCommand(&ssm.SendCommandInput{
		InstanceIds:  []*string{aws.String(instanceId)},
		DocumentName: aws.String("AWS-RunShellScript"),
		Parameters: map[string][]*string{
			"commands": {
				aws.String(cmdstring),
			},
		},
	})

	if err != nil {
		log.Fatalf("Failed to send command: %v", err)
		return
	}

	// 4. コマンド実行結果の取得
	commandID := output.Command.CommandId
 
	time.Sleep(5 * time.Second) // 5秒待つ
    result, err := ssmClient.GetCommandInvocation(&ssm.GetCommandInvocationInput{
		CommandId:  commandID,
		InstanceId: aws.String(instanceId),
	})
	if err != nil {
		log.Fatalf("Failed to get command result: %v", err)
		return
	}

	// コマンドの出力を表示
	fmt.Printf("Command output: %s\n", *result.StandardOutputContent)

コードの説明

次の処理をおこなっています。

  1. AWSセッションの作成
    AWS SDKのセッションを作成します。リージョンとプロファイルを指定して、AWSリソースにアクセスするための設定を行います

  2. SSMクライアントの作成
    作成したセッションを使用して、SSMクライアントを初期化しています。

  3. コマンドの設定と送信
    SendCommandメソッドを使用して、指定したEC2のインスタンスにコマンドを送信しています。AWS-RunShellScriptドキュメントを使用して、シェルコマンドを実行するように設定しています

  4. コマンド実行結果の取得
    ssmClient.SendCommandが実行完了までまたないため、5秒間WaitしたのGetCommandInvocationメソッドを使用して、実行したコマンドの結果を取得させていますが、実際には、result.statusがsuccessになるまでループさせて待つ方法がいいと思います。

おわりに

GoのAWS SDKを使用してEC2インスタンスにコマンドを実行し、その結果を取得しました。セキュリティと権限の管理には気を付ける必要がありますが、プログラムによる制御でリモートからコマンドを実行できるため、運用や管理が自動化、効率化できると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?