🎉

[Ansible]セッションマネージャー経由でSSH接続する

2021/05/04に公開

EC2 インスタンスがプライベートサブネットにあり、ローカル環境から直接 SSH 接続できない場合、セッションマネージャーを使用すると SSH 接続できます。セッションマネージャー経由で SSH 接続するメリットは以下のブログがたいへん参考になりました。

セッションマネージャー越しにSSHアクセスすると何が嬉しいのか | DevelopersIO

接続先 EC2 インスタンスの設定

SSM マネージャーをインストールしておく必要があります。Amazon Linux 2の AMI から起動している場合はすでにインストールされていますので次のステップに進んでください。

インストール方法はドキュメントをご参照ください。

Manually install SSM Agent on EC2 instances for Linux - AWS Systems Manager

接続元(ローカル環境)の設定

セッションマネージャープラグインをインストールする必要があります。インストール方法は以下のドキュメントをご参照ください。

(Optional) Install the Session Manager plugin for the AWS CLI - AWS Systems Manager

スタティックインベントリの場合

EC2 インスタンスをインベントリファイルに記載している場合、以下のように記載します。

; static_ec2.ini
[instance]
instance1 ansible_host=i-xxxxxxxxxxxx

[all:vars]
ansible_ssh_common_args=-o StrictHostKeyChecking=no -o ProxyCommand="sh -c \"aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'\""
ansible_user='ec2-user'
ansible_become=true
ansible_ssh_private_key_file='~/.ssh/<KEY_PAIR>.pem'

以下のようなコマンドでプレイブックを実行できます。

$ ansible-playbook -i static_ec2.ini <プレイブックファイル>

ダイナミックインベントリの場合

EC2 インスタンスを動的に取得して管理する場合はダイナミックインベントリを利用します。ダイナミックインベントリについては以下の記事をご参照ください。

[Ansible]インベントリプラグインを使ってEC2インスタンス情報を動的に取得する

インベントリファイルを以下のようにします。

# aws_ec2.yml
plugin: aws_ec2
regions:
  - ap-northeast-1

# フィルタの設定
# 起動しているEC2インスタンスのみを対象とする
filters:
  instance-state-name: running

# グルーピングの設定
# タグ毎にEC2インスタンスのグループをまとめる
keyed_groups:
  - key: tags.Application
    prefix: tag_Name_
    separator: ""

# inventory_hostnameの設定項目の優先順位
# 上から優先され、取得できなければ下にいく
hostnames:
  - tag:Name
  - private-ip-address

compose:
  # SSM Session Managerでホストに接続するためansible_hostをEC2インスタンスIDにする
  ansible_host: instance_id

プレイブックは以下のようにします。vars に接続情報を記載します。

# example.yml
---
- name: Example dynamic inventory
  hosts: "{{ target_hosts }}"

  vars:
    ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o ProxyCommand='aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p''"
    ansible_user: ec2-user
    ansible_ssh_private_key_file: ~/.ssh/<KEY PAIR>.pem

  tasks:
    - name: Print Name tag
      debug:
        msg: "{{ tags.Name }}"

以下のようなコマンドでプレイブックを実行できます。

$ ansible-playbook -i aws_ec2.yml example.yml

参考

Discussion