SSM SessionManagerでのコンソールの操作ログをS3やCloudWatchLogsに保存できるということなので試してみた。Terraformで設定。
1. IAMrole / Instance Profileを作成
ec2インスタンスにインストールされているSSMエージェントがログを書き込むので、インスタンスに権限を付与してあげる必要がある。こちらのドキュメントを参考に設定。今回は AmazonSSMManagedInstanceCore に権限を追加してみた。Terraformのコードはこんな感じ。
data "aws_iam_policy" "amazon_ssm_managed_instance_core" {
arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
data "aws_iam_policy_document" "ec2_ssm_test_policy_doc" {
source_json = data.aws_iam_policy.amazon_ssm_managed_instance_core.policy
statement {
effect = "Allow"
resources = ["*"]
actions = [
"s3:PutObject",
"s3:GetEncryptionConfiguration",
"logs:PutLogEvents",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"ssm:GetParameter",
"ssm:GetParameters",
"ssm:GetParametersByPath",
"kms:Decrypt",
"kms:GenerateDataKey",
]
}
}
resource "aws_iam_policy" "ec2_ssm_test_policy" {
name = "ec2-ssm-test-policy"
policy = data.aws_iam_policy_document.ec2_ssm_test_policy_doc.json
}
resource "aws_iam_role" "ec2_ssm_test_role" {
name = "ec2-ssm-test-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
tags = {
Name = "ec2-ssm-test-role"
}
}
resource "aws_iam_role_policy_attachment" "ssm_role_attachment" {
role = aws_iam_role.ec2_ssm_test_role.name
policy_arn = aws_iam_policy.ec2_ssm_test_policy.arn
}
resource "aws_iam_instance_profile" "ec2_ssm_test_profile" {
name = "ec2-ssm-test-profile"
role = aws_iam_role.ec2_ssm_test_role.name
}
2. 作成したinstance profileをアタッチしたec2インスタンスを作成
amazon linux2を利用*1。Terraformのコードはこんな感じ。VPCとかSubnet、SecurityGroupは適宜設定。
data "aws_ssm_parameter" "amzn2_ami" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
resource "aws_instance" "ssm_test_server" {
ami = data.aws_ssm_parameter.amzn2_ami.value
instance_type = "t2.micro"
subnet_id = aws_subnet.ec2_ssm_test_private_subnet.id
iam_instance_profile = aws_iam_instance_profile.ec2_ssm_test_profile.name
security_groups = [
aws_security_group.allow_http.id,
]
tags = {
Name = "ssm-test-server"
}
user_data = <<EOF
#!/bin/bash
yum update -y
amazon-linux-extras install docker
usermod -aG docker ec2-user
systemctl enable docker
systemctl start docker
EOF
}
3. SSM SessionManager設定用Documentの作成
SSM SessionManagerの設定はSSM Documentで作成するようなので、terraformで作成。今回はテストなので暗号化はしない設定。ログ保存用のS3 bucketとCloudWatchLogsのLogGroupも一緒に作成。因みにDocumentの名前は "SSM-SessionManagerRunShell"にしておくとよい。session mamager使う時にデフォルトで読み込んでくれる。勿論名前変えて、CLIの引数で渡して指定することも可能*2。
resource "aws_s3_bucket" "ec2_ssm_test_log_bucket" {
bucket = "ec2-ssm-test-log-bucket-xxx"
force_destroy = true
lifecycle_rule {
enabled = true
expiration {
days = 3
}
}
}
resource "aws_cloudwatch_log_group" "ec2_ssm_test_log" {
name = "/ec2-ssm-test-log"
retention_in_days = 3
}
resource "aws_ssm_document" "session_manager_run_shell" {
name = "SSM-SessionManagerRunShell"
document_type = "Session"
document_format = "JSON"
content = <<EOF
{
"schemaVersion": "1.0",
"description": "Document to hold regional settings for Session Manager",
"sessionType": "Standard_Stream",
"inputs": {
"s3BucketName": "${aws_s3_bucket.ec2_ssm_test_log_bucket.id}",
"s3EncryptionEnabled": false,
"cloudWatchLogGroupName": "${aws_cloudwatch_log_group.ec2_ssm_test_log.name}",
"cloudWatchEncryptionEnabled": false
}
}
EOF
}
いざapplyと思って実行するとエラー。SSM-SessionManagerRunShell が存在するとのこと。どうもSSMを使ったことがあると自動で作成されている模様。消す*3かimportすればよさそう。今回はimportしちゃった。
$ terraform import --target aws_ssm_document.session_manager_run_shell SSH-SessionManagerRunShell aws_ssm_document.session_manager_run_shell: Importing from ID "SSM-SessionManagerRunShell"... aws_ssm_document.session_manager_run_shell: Import prepared! Prepared aws_ssm_document for import aws_ssm_document.session_manager_run_shell: Refreshing state... [id=SSM-SessionManagerRunShell] Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform.
無事importできた。その後applyすると無事適用できました。
$ terraform apply ...
4. 確認
- ログはSessionを終了すると保存される模様
- CloudWatch、S3ともに保存できてました。CloudWatchLogsだとこんな感じ。文字化けしてるけど、コンソールで実行したコマンド、その結果ちゃんと保存できてる。
Script started on 2020-10-18 13:32:11+0000 [?1034hsh-4.2$ [Ksh-4.2$ bash ]0;@ip-10-0-1-xxx:/usr/bin[?1034h[ssm-user@ip-10-0-1-xxx bin]$ sudo su - ec2-use ]0;ec2-user@ip-10-0-1-xxx:~[ec2-user@ip-10-0-1-xxx ~]$ uname -a Linux ip-10-0-1-xxx.ap-northeast-1.compute.internal 4.14.193-149.317.amzn2.x86_64 #1 SMP Thu Sep 3 19:04:44 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux ]0;ec2-user@ip-10-0-1-xxx:~[ec2-user@ip-10-0-1-xxx ~]$ hostname ip-10-0-1-xxx.ap-northeast-1.compute.internal ]0;ec2-user@ip-10-0-1-xxx:~[ec2-user@ip-10-0-1-xxx ~]$ uptime 13:26:27 up 5 min, 0 users, load average: 0.02, 0.12, 0.08 ]0;ec2-user@ip-10-0-1-xxx:~[ec2-user@ip-10-0-1-xxx ~]$ whoami ec2-user ]0;ec2-user@ip-10-0-1-xxx:~[ec2-user@ip-10-0-1-xxx ~]$ exit logout ]0;@ip-10-0-1-xxx:/usr/bin[ssm-user@ip-10-0-1-xxx bin]$ exit exit sh-4.2$ exit exit Script done on 2020-10-18 13:32:11+0000