【AWS】コマンド一発にECSコンテナに入る方法

## はじめに
ECS ExecをするためにタスクIDを見にいくことからおさらばするための記事です📝

[ECS exec](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html)が可能になって、結構な月日がだったように思います。
今日は、ECSコンテナに一発で入るコマンドを紹介します。


## まず結論
#### コマンド
```
aws ecs execute-command \
  --region ap-northeast-1 \
  --cluster cluster \
  --task $(aws ecs list-tasks --cluster cluster | jq '.taskArns[0]' -r) \
  --container web \
  --interactive \
  --command "/bin/bash"
```
※引数のcluster名、コンテナ名を指定してください。

## 解説
1. `aws ecs list-tasks`でクラスターのタスクのARNを取得します。
2. それ引数に渡して、`aws ecs execute-command`を実行しています。

## 準備(Macの場合)
**1**. jqコマンドをインストール
```
brew install jq
```
**2**. aws cliをインストール
```
sudo ln -s /folder/installed/aws-cli/aws /usr/local/bin/aws
sudo ln -s /folder/installed/aws-cli/aws_completer /usr/local/bin/aws_completer
```
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

**3**. Session Managerプラグインをインストール
```
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
```
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html


## ECSの構築
```typescript
import { Aspects, aws_ecs, aws_ecs_patterns, aws_iam, IAspect, Stack, StackProps } from 'aws-cdk-lib';
import { Vpc } from 'aws-cdk-lib/aws-ec2';
import { CfnService } from 'aws-cdk-lib/aws-ecs';
import { Construct, IConstruct } from 'constructs';

class EnableExecuteCommand implements IAspect {
  public visit(node: IConstruct): void {
    if (node instanceof CfnService) {
      node.addOverride('Properties.EnableExecuteCommand', true);
    }
  }
}

export class EcsExecDemoStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    const vpc = new Vpc(this, 'Vpc', {
      cidr: '10.0.0.0/16',
    });

    const cluster = new aws_ecs.Cluster(this, 'cluster', {
      vpc,
      clusterName: 'cluster'
    });

    const loadBalancedFargateService = new aws_ecs_patterns.ApplicationLoadBalancedFargateService(
      this,
      'fargate',
      {
        cluster,
        desiredCount: 1,
        taskImageOptions: {
          image: aws_ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
        },
        publicLoadBalancer: true,
      }
    )

    // ECS execを有効化する
    loadBalancedFargateService.taskDefinition.taskRole.addToPrincipalPolicy(
      new aws_iam.PolicyStatement({
        actions: [
          'ssmmessages:CreateControlChannel',
          'ssmmessages:CreateDataChannel',
          'ssmmessages:OpenControlChannel',
          'ssmmessages:OpenDataChannel',
        ],
        resources: ['*'],
      }),
    );
    Aspects.of(loadBalancedFargateService).add(new EnableExecuteCommand());
  }
}
```
AWS CDK(TypeScript)で構築しています。



## コマンド実行した時の挙動
上記のデプロイ完了後にコマンドを実行します。

```bash
$ aws ecs execute-command \
>   --region ap-northeast-1 \
>   --cluster cluster \
>   --task $(aws ecs list-tasks --cluster cluster | jq '.taskArns[0]' -r) \
>   --container web \
>   --interactive \
>   --command "/bin/bash"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-061544f141048a53c
bash-4.2# ls
bin  boot  dev	etc  home  lib	lib64  local  managed-agents  media  mnt  opt  proc  root  run	sbin  srv  sys	tmp  usr  var
```
無事、コンテナの中に入れました！！！


## 終わりに
皆さんの快適な開発ライフを心から願っています🙏

## 参考

- [AWS CDKでECS構築](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/tutorial-ecs-web-server-cdk.html)
- [AWS CDKでECS execを有効にする](https://zenn.dev/xeres/articles/2021-12-08-aws-cdk-ecs-patterns-and-ecs-exec)