AWS Session Manager & Run Command로 외부에서 쉘 스크립트 실행하기

AWS의 Systems Manager에는 Run CommandSession Manager라는 기능이 있습니다.

SSH를 이용하여 EC2 인스턴스에 접근할 때는 SSH 키 페어가 필요하고, SSH 접속을 위한 보안 그룹을 열어야 하는데요. 위 기능을 이용하면 이러한 과정을 생략하고 원격에서 EC2 인스턴스에 접근하여 명령을 실행할 수 있습니다.

먼저, Session Manager로 웹 브라우저에서 쉘을 실행하는 방법부터 설명드리겠습니다.

Session Manager로 웹 브라우저에서 쉘 실행하기

Session Manager로 웹 브라우저에서 쉘을 실행하려면, EC2 인스턴스가 Systems Manager와 관련된 작업을 실행할 수 있는 권한을 부여해야 합니다.

먼저 EC2 서비스에 대한 신뢰 정책을 생성합니다. 아래 내용을 복사하여 임의의 파일 이름으로 저장합니다. (저는 assume-role.json이라는 파일 이름으로 저장했습니다)

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }
}

저장한 파일 이름을 이용해서 다음 명령으로 IAM Role을 생성합시다. 그리고 SSM을 EC2에서 사용할 수 있도록 하기 위해 AmazonEC2RoleforSSM Policy를 연결해 줍니다.

aws iam create-role --role-name AWSSSMTestRole --assume-role-policy-document file://./assume-role.json
aws iam attach-role-policy --role-name AWSSSMTestRole \
    --policy-arn "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"

CLI로 작업하는 경우, 인스턴스 프로파일에 생성한 Role을 추가해야 합니다. (콘솔로 작업하는 경우, IAM Role 생성 시 자동으로 수행됩니다.)

aws iam create-instance-profile --instance-profile-name AWS_SSM_Instance_Profile
aws iam add-role-to-instance-profile --instance-profile-name AWS_SSM_Instance_Profile --role-name AWSSSMTestRole

콘솔로 작업하시려면 링크한 문서의 1단계를 실행해 주세요.

이제 EC2 인스턴스를 생성합니다. 이미지 ID는 x64 버전의 Amazon Linux 2 이미지 ID입니다. 키 이름은 생성하신 키 페어 이름을 적으면 됩니다. 없으시다면 이 문서를 참고해서 만들어 주세요.

aws ec2 run-instances --iam-instance-profile Name=AWS_SSM_Instance_Profile \ 
     --instance-type t3.nano \ 
     --key-name <your-key-pair-name> \ 
     --image-id ami-08c64544f5cfcddd0

조금 기다리면 EC2 인스턴스가 생성되어 있을 겁니다. 그리고 Systems Manager 콘솔로 이동합니다. 왼쪽 아래를 보면 Session Manager라는 메뉴가 있는데요. 이 메뉴를 클릭합니다.

Session Manager 메뉴를 클릭하면 우측에 Start Session 버튼이 있습니다. (위의 스크린샷 참조) 이 버튼을 클릭합니다.

방금 생성한 인스턴스를 선택하고, 아래의 Start Session 버튼을 클릭합니다.

그러면 아래 스크린샷과 같이 쉘 화면이 실행된 것을 볼 수 있습니다. 종료하려면 우측 상단의 Terminate 버튼을 클릭하거나, exit 명령을 치면 됩니다.

참고로, Session Manager를 사용한 경우 실행 중인 사용자는 ssm-user, 로케일 설정은 C.UTF-8으로 되어 있는 것을 확인할 수 있습니다. (위의 스크린샷 참조)

Run Command로 원격으로 쉘 스크립트 실행하기

아직 EC2 인스턴스를 끝내지 않으셨다면, 인스턴스 ID(i-...으로 시작하는 값)를 메모해 주시기 바랍니다.

이번에는 원격으로 쉘 스크립트를 실행하는 작업을 해 보겠습니다.

Boto3가 설치되어 있다면, 아래와 같이 스크립트를 작성해 봅니다.

import boto3

ssm = boto3.client('ssm')

response = ssm.send_command(
    InstanceIds=['i-your_instance_id'],
    DocumentName='AWS-RunShellScript',
    Parameters={
        "commands": [
            "echo 'Run command as ...'",
            "whoami",
            "echo 'Current locale ...'",
            "locale"
        ]
    },
    OutputS3BucketName='your-bucket-name'
)

Run Command의 결과는 S3나 CloudWatch Logs로 내보낼 수 있습니다. 물론 필수가 아니기 때문에 생략할 수도 있는데요. 자세한 것은 Boto3 문서를 참고해 주세요.

  • S3로 output을 내보내는 경우: send_command() 호출 시 OutputS3BucketName, OutputS3KeyPrefix 파라미터를 사용
  • CloudWatch Logs로 output을 내보내는 경우: send_command() 호출 시 CloudWatchOutputConfig 파라미터를 사용

이 스크립트를 실행하면, S3에 stdout 내용이 올라와 있는 것을 보실 수 있습니다. 내용은 다음과 같습니다.

Run command as ...
root
Current locale ...
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

즉, send_command()를 사용하면 root 계정으로 스크립트의 내용을 실행하고, 로케일 설정은 기본값으로 주어집니다. 이 경우, 실행할 명령에 한글이 섞여 있을 때 에러가 발생할 수 있으니 유의하시기 바랍니다. 그리고 SSM Agent는 root 계정으로 실행하기 때문에, 해당 작업에 대한 권한 부여는 최대한 제한하는 게 좋겠네요.

리소스 정리

테스트가 끝나셨다면 인스턴스를 종료해 주셔야 과금되지 않습니다.

aws ec2 terminate-instances --instance-ids i-your_instance_id

추가로, 과금되는 건 아니지만 IAM Role도 삭제해 보겠습니다. 먼저 인스턴스 프로파일에서 IAM Role 연결을 끊고, 인스턴스 프로파일을 삭제합니다.

aws iam remove-role-from-instance-profile --instance-profile-name AWS_SSM_Instance_Profile --role-name AWSSSMTestRole
aws iam delete-instance-profile --instance-profile-name AWS_SSM_Instance_Profile

마무리로 IAM Role과 Policy 간 연결을 해제하고 Role을 삭제합니다.

aws iam detach-role-policy --role-name AWSSSMTestRole \ 
    --policy-arn "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
aws iam delete-role --role-name AWSSSMTestRole

참고자료