[旧情報] Cloud Formationを使ったSysdig Fargate Serverless Agent 4.0のインストール（Orchestrator Agent使用版）

:::note warn
本手順はOrchestrator Agentを使用した古いデプロイ方法になります。最新のデプロイ方法についてはTerraform版の下記記事をご参照ください。
https://qiita.com/yotake/items/6e5963e3e6e08ea9f64f
:::
先日、Sysdig Fargate Serverless Agent 4.0がリリースされました。Sysdig Fargate Serverless Agentは、AWS Fargate on ECSのランタイム脅威検知が可能となるSysdigのAgentです。Sysdig Fargate Serverless Agentは以下の方法でインストールできます。
* Terraformによるインストール
* Cloud Formationによるインストール
* 手動でのインストール

バージョン4.0ではCloud Formationによるインストール手順が変わったので、新しい手順をご紹介します。

# 参照ドキュメント
https://docs.sysdig.com/en/docs/installation/sysdig-secure/install-agent-components/ecs-on-fargate/serverless-agents/cloudformation/

# serverless-patcherの準備
serverless-patcherは、FargateタスクをデプロイするためのCloud Formationテンプレートを変更し、Sysdig Fargate Serverless Agentをサイドカーとしてデプロイするように書き換えてくれるツールです。
事前準備として、serverless-patcherイメージを、Fargateタスクをデプロイするのと同じリージョンのプライベートECRリポジトリにプッシュしておきます。

まず、serverless-patcherを手元にプルします。
```
docker pull quay.io/sysdig/serverless-patcher:latest
```

ECRにログインします。
```
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <AWS_Account_ID>.dkr.ecr.ap-northeast-1.amazonaws.com
```
serverless-patcherのImage IDを確認します。
```
docker image ls
```
Imageにタグを付けます。
```
docker tag 571f363b1e9f <AWS_Account_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/yo-repo:latest
```
ECRにプッシュします。
```
docker push <AWS_Account_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/yo-repo:latest
```

# Orchestrator Agentのデプロイ
Orchestrator Agentは、サイドカーとして各タスクにデプロイするWorkload Agentからの通信を束ねて、Sysdig SaaSバックエンドと通信する役割を担います。
下記 `orchestrator-agent.yaml` をCloud Formationテンプレートとして使用します。
https://download.sysdig.com/dependencies/serverless/fargate/orchestrator-agent.yaml

自身の環境に合わせて必要なパラメータを設定します（下記は私が設定したパラメータ一覧です）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/8e40519c-c1b9-5e44-4a24-efc78a100662.png)

:::note
**SysdigCollectorHost**の値は利用しているSysdig SaaSリージョンにより異なります。下記ドキュメントをご参照ください。
https://docs.sysdig.com/en/docs/administration/saas-regions-and-ip-ranges/
:::

デプロイが完了すると、Orchestrator AgentをSysdig UI上で確認できます。
**Integrations > Data Sources > Sysdig Agents** に移動します。
`Deployment Type` が **fargate** のSysdig Agentが接続されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/6d3710d5-9bcc-3075-45fe-85c05ea09377.png)


# Instrumentation Stackのデプロイ
Instrumentation Stackは、Fargateタスク用テンプレートに対してserverless-patcherを適用するための環境を用意します。
下記 `instrumentation.yaml` をCloud Formationテンプレートとして使用します。
https://download.sysdig.com/dependencies/serverless/fargate/instrumentation.yaml

自身の環境に合わせて必要なパラメータを設定します（下記は私が設定したパラメータ一覧です）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/600d90fb-2aac-70e0-8b7e-db9e53d07820.png)
"`Orchestrator Agent Host`"には、先ほどデプロイしたOrchestrator Agent Stackのoutputから値を貼り付けます。
"`Sysdig Serverless Patcher Image`"には、先ほどECRにプッシュしたServerless PatcherイメージのURIを入力します。 

# Fargateタスク　＋　Workload Agentのデプロイ
下記 `sysdig-serverless-sample-application.yml`をサンプルのCloud Formationテンプレートとして使用します。
このサンプルアプリケーションはSysdigの検知イベントを発生させるイベントジェネレーターです。
https://github.com/polar3130/sysdig-for-fargate-playground/blob/main/sysdig-serverless-sample-application.yml

以下の変換マクロをサンプルテンプレートのルートレベルに追加します。
変換マクロの名称（例：SysdigMacro）は先ほどデプロイしたInstrumentation Stackのoutput結果から確認できます。
`Transform: ["SysdigMacro"]`


既存の下記記述は削除します。
```
Transform: 
  - MySysdigMacro
```

Fargateタスクを配置するVPCでInternet Gatewayを使用している場合（=NAT Gatewayではない場合）には、`AssignPublicIp`を**ENABLED**に変更してください。
```
AssignPublicIp: ENABLED
``` 

サンプルのCloud Formationテンプレート例：
```
AWSTemplateFormatVersion: '2010-09-09'


Transform: ["SysdigMacro"]


Parameters:
VpcId:
  Type: AWS::EC2::VPC::Id
ProtectedSubnets:
  Type: List<AWS::EC2::Subnet::Id>
TaskCpu:
  Type: Number
  Default: 256
TaskMemory:
  Type: Number
  Default: 512
DesiredCount:
  Type: Number
  Default: 1


Resources:
SecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupName: event-generator
    GroupDescription: Security group for the service
    VpcId: !Ref VpcId


SecurityGroupIngress:
  Type: AWS::EC2::SecurityGroupIngress
  Properties:
    GroupId: !Ref SecurityGroup
    IpProtocol: -1
    SourceSecurityGroupId: !Ref SecurityGroup


Cluster:
  Type: AWS::ECS::Cluster
  Properties:
    ClusterName: sysdig-event-generator


LogGroup:
  Type: AWS::Logs::LogGroup
  Properties:
    LogGroupName: /ecs/event-generator


EcsTaskRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Principal:
            Service:
              - ecs-tasks.amazonaws.com
              - events.amazonaws.com
          Action:
            - sts:AssumeRole
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole
    RoleName: task-role-for-event-generator


EcsTaskRolePolicy:
  Type: AWS::IAM::Policy
  Properties:
    PolicyName: task-role-policy-for-event-generator
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - ssmmessages:CreateControlChannel
            - ssmmessages:CreateDataChannel
            - ssmmessages:OpenControlChannel
            - ssmmessages:OpenDataChannel
          Resource: '*'
    Roles:
      - Ref: EcsTaskRole


TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    Family: event-generator
    RequiresCompatibilities:
      - FARGATE
    Cpu: !Ref TaskCpu
    Memory: !Ref TaskMemory
    NetworkMode: awsvpc
    ExecutionRoleArn: ecsTaskExecutionRole
    TaskRoleArn: !GetAtt EcsTaskRole.Arn
    ContainerDefinitions:
      - Name: event-generator
        Image: falcosecurity/event-generator:latest
        EntryPoint:
          - "/bin/event-generator"
        Command:
          - "run"
          - "syscall"
          - "--loop"
        LogConfiguration:
          LogDriver: awslogs
          Options:
            awslogs-region: !Ref 'AWS::Region'
            awslogs-group: !Ref LogGroup
            awslogs-stream-prefix: app
        Essential: true


Service:
  Type: AWS::ECS::Service
  Properties:
    Cluster: !Ref Cluster
    EnableExecuteCommand: true
    DeploymentConfiguration:
      MaximumPercent: 200
      MinimumHealthyPercent: 100
    DesiredCount: !Ref DesiredCount
    LaunchType: FARGATE
    NetworkConfiguration:
      AwsvpcConfiguration:
        AssignPublicIp: ENABLED
        SecurityGroups:
          - !Ref SecurityGroup
        Subnets: !Ref ProtectedSubnets
    ServiceName: event-generator-service
    TaskDefinition: !Ref TaskDefinition
```


# ECSタスク定義の確認
AWSマネージメントコンソールから、ECSのタスク定義を確認します。
serverless-patcherによる変換後のタスク定義は以下になります。

:::note
Sysdig Fargate Serverless Agentをサイドカーとしてデプロイするために必要な記述（例：entryPointの"/opt/draios/bin/instrument"や環境変数など）が追加されていることが確認できます。
:::
```
{
    "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:487433680518:task-definition/event-generator:9",
    "containerDefinitions": [
        {
            "name": "event-generator",
            "image": "falcosecurity/event-generator:latest",
            "cpu": 0,
            "links": [],
            "portMappings": [],
            "essential": true,
            "entryPoint": [
                "/opt/draios/bin/instrument"
            ],
            "command": [
                "/bin/event-generator",
                "run",
                "syscall",
                "--loop"
            ],
            "environment": [
                {
                    "name": "SYSDIG_COLLECTOR",
                    "value": ""
                },
                {
                    "name": "SYSDIG_ORCHESTRATOR",
                    "value": "Orche-Sysdi-A89XQ9PRFHLY-23a7d72187ecdbe7.elb.ap-northeast-1.amazonaws.com"
                },
                {
                    "name": "SYSDIG_ORCHESTRATOR_PORT",
                    "value": "6667"
                },
                {
                    "name": "SYSDIG_COLLECTOR_PORT",
                    "value": ""
                },
                {
                    "name": "SYSDIG_LOGGING",
                    "value": "info"
                },
                {
                    "name": "SYSDIG_ACCESS_KEY",
                    "value": ""
                }
            ],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [
                {
                    "sourceContainer": "SysdigInstrumentation",
                    "readOnly": true
                }
            ],
            "linuxParameters": {
                "capabilities": {
                    "add": [
                        "SYS_PTRACE"
                    ],
                    "drop": []
                },
                "devices": [],
                "tmpfs": []
            },
            "secrets": [],
            "dnsServers": [],
            "dnsSearchDomains": [],
            "extraHosts": [],
            "dockerSecurityOptions": [],
            "dockerLabels": {},
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/event-generator",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "app"
                },
                "secretOptions": []
            },
            "systemControls": []
        },
        {
            "name": "SysdigInstrumentation",
            "image": "quay.io/sysdig/workload-agent:4.0.0",
            "cpu": 0,
            "links": [],
            "portMappings": [],
            "essential": true,
            "entryPoint": [
                "/opt/draios/bin/logwriter"
            ],
            "command": [],
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "secrets": [],
            "dnsServers": [],
            "dnsSearchDomains": [],
            "extraHosts": [],
            "dockerSecurityOptions": [],
            "dockerLabels": {},
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "Instrumentation-stack-SysdigLogGroup-sB1nGtxsOTzE",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "TaskDefinition"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
    ],
    "family": "event-generator",
    "taskRoleArn": "arn:aws:iam::487433680518:role/task-role-for-event-generator",
    "executionRoleArn": "arn:aws:iam::487433680518:role/ecsTaskExecutionRole",
    "networkMode": "awsvpc",
    "revision": 9,
    "volumes": [],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.17"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.22"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "name": "ecs.capability.task-eni"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "256",
    "memory": "512",
    "registeredAt": "2023-02-25T08:32:36.790Z",
    "registeredBy": "arn:aws:iam::487433680518:user/bobo3977",
    "tags": []
}
```

# Sysdig Fargate Serverless Agentの稼働確認
Fargateタスクとして稼働しているイベントジェネレータによって発生したイベントをSysdig Fargate Serverless Agentで検知できていることを確認します。

Sysdig UIにログインします。
**Events**に移動します。
Fargateタスク上で発生したイベントが記録されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802821/4b4cb5ce-8600-92cc-cba6-1a33562efbcd.png)

# まとめ
Cloud Formationとserverless-patcherを使用することで、ワークロードのタスク定義を手動で書き換えることなく、Sysdig Fargate Serverless Agentをサイドカーとしてデプロイできることが確認できました。