SSM SessionManagerのログをS3 bucket/CloudWatchLogに保存する
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