AWS Fargate에서 OCI CLI 실행 가능

날과 씨


Athena로 OCI Object Storage에 저장된 데이터(구체적으로 감사 로그)를 분석하기 위해서는 로그 파일을 S3로 가져와 방법을 연구해야 한다.
나름의 지식과 가용한 굿즈 서비스가 많아 AWS에서 처리를 수행하기로 했지만, 램바다와 팜게이트, 파이썬과 셸스크립트, OCI CLI와 S3 호환 API 등 기술을 활용한 선택이 있었다.
Fargate가 OCI CLI 및 AWS CLI를 실행하는 것은 다음 사항에서 결정됩니다.
  • Lambda에 사용된 저장 장치는 512MB여서 로그를 다운로드할 때 용량이 불안하지만 Fargate(1.4.0)일 경우 20GB를 사용할 수 있다.
  • 각종 SDK
  • 에서 OCI와 AWS는 bulk-downloads3 sync 같은 고급 명령을 집행할 수 없다.
  • OCI ObjectStage는 S3 호환 API지원되는 API를 갖추고 있으나 일부분에 한한다.
  • OCI 인증 정보 처리


    OCI CLI를 실행하려면 config 파일과 개인 키가 필요합니다.
    SDK 및 CLI 구성 파일
    Dcoker image에 인증 정보를 직접 삽입하지 않으려면 config 파일과 기밀 키를 AWS Secrets Manager에 바이너리 데이터로 저장하고 Fargate 작업을 시작할 때 가져옵니다.Terraform으로 바이너리 데이터의 비밀을 만들 때는 다음과 같다.
    # config
    resource "aws_secretsmanager_secret" "oci-config" {
      name = "oci-config"
    }
    
    resource "aws_secretsmanager_secret_version" "oci-config" {
      secret_id     = aws_secretsmanager_secret.oci-config.id
      secret_binary = filebase64("docker/oci-cli/.oci/config")
    }
    
    # 秘密鍵
    resource "aws_secretsmanager_secret" "oci-apikey" {
      name = "oci-apikey"
    }
    
    resource "aws_secretsmanager_secret_version" "oci-apikey" {
      secret_id     = aws_secretsmanager_secret.oci-apikey.id
      secret_binary = filebase64("docker/oci-cli/.oci/oci_api_key.pem")
    }
    
    타스크롤에서 Secrets Manager의 권한을 Fargate에 넘깁니다.
    data "aws_iam_policy_document" "ecs-tasks-assume-role-policy" {
      statement {
        effect  = "Allow"
        actions = ["sts:AssumeRole"]
    
        principals {
          type        = "Service"
          identifiers = ["ecs-tasks.amazonaws.com"]
        }
      }
    }
    
    resource "aws_iam_role" "ecs-task-role" {
      name               = "ecs-task-role"
      assume_role_policy = data.aws_iam_policy_document.ecs-tasks-assume-role-policy.json
    }
    
    data "aws_iam_policy_document" "ecs-task-secretsmanager" {
      statement {
        effect = "Allow"
    
        actions = [
          "secretsmanager:GetSecretValue",
        ]
    
        resources = [
          aws_secretsmanager_secret.oci-config.arn,
          aws_secretsmanager_secret.oci-apikey.arn
        ]
      }
    }
    
    resource "aws_iam_policy" "ecs-task-secretsmanager" {
      name   = "ecs-task-secretsmanager"
      policy = data.aws_iam_policy_document.ecs-task-secretsmanager.json
    }
    
    resource "aws_iam_role_policy_attachment" "ecs-task-role_ecs-task-secretsmanager" {
      role       = aws_iam_role.ecs-task-role.name
      policy_arn = aws_iam_policy.ecs-task-secretsmanager.arn
    }
    
    또한 OCI 환경에서 OCI CLI와 SDK인스턴스 프린터를 실행할 경우 AWS의 IAM Role 등의 기능을 통해 인증 정보를 동적으로 전달할 수 있다.

    기타 자원


    ECS 및 ECR을 설정합니다.
    resource "aws_ecr_repository" "oci-cli" {
      name                 = oci-cli
      image_tag_mutability = "MUTABLE"
    
      image_scanning_configuration {
        scan_on_push = true
      }
    }
    
    resource "aws_ecs_cluster" "oci-cli" {
      name = "oci-cli-cluster"
    
      setting {
        name  = "containerInsights"
        value = "enabled"
      }
    }
    
    resource "aws_ecs_task_definition" "oci-cli" {
      family = oci-cli
      container_definitions = templatefile(
        "ecs/task-definition/oci-cli.json",
        {
          region       = var.aws_region
          image        = "${aws_ecr_repository.oci-cli.repository_url}:latest"
          name         = oci-cli
          compartment  = var.compartment
          ociconfig    = aws_secretsmanager_secret.oci-config.name
          ociapikey    = aws_secretsmanager_secret.oci-apikey.name
        }
      )
    
      execution_role_arn       = "arn:aws:iam::${data.aws_caller_identity.self.account_id}:role/ecsTaskExecutionRole"
      task_role_arn            = aws_iam_role.ecs-task-role.arn
      requires_compatibilities = ["FARGATE"]
      network_mode             = "awsvpc"
      cpu                      = 256
      memory                   = 512
    }
    
    작업 정의 설정에서 읽을 템플릿입니다.
    [
      {
        "logConfiguration": {
          "logDriver": "awslogs",
          "secretOptions": null,
          "options": {
            "awslogs-group": "/ecs/${name}",
            "awslogs-region": "${region}",
            "awslogs-stream-prefix": "ecs"
          }
        },
        "name": "${name}",
        "image": "${image}",
        "essential": true,
        "environment": [
          {
            "name": "COMPARTMENT",
            "value": "${compartment}"
          },
          {
            "name": "OCICONFIG",
            "value": "${ociconfig}"
          },
          {
            "name": "OCIAPIKEY",
            "value": "${ociapikey}"
          }
        ]
      }
    ]
    
    OCI CLI 및 AWS CLI의 Docker file을 설치합니다.다무대 빌딩 같은 일을 한 번 했지만 개선할 여지가 있다고 생각해요.
    # AL2 image Tag
    ARG AL2Tag="2.0.20200722.0"
    
    # build
    FROM amazonlinux:${AL2Tag} AS builder
    
    COPY requirements.txt /root
    
    RUN yum install -y unzip python3-pip && \
        curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
        unzip awscliv2.zip && \
        ./aws/install --bin-dir /aws-cli-bin/ && \
        pip3 install -r /root/requirements.txt
    
    # deploy
    FROM amazonlinux:${AL2Tag}
    
    COPY --from=builder /usr/local/aws-cli/ /usr/local/aws-cli/
    COPY --from=builder /aws-cli-bin/ /usr/local/bin/
    COPY --from=builder /root/.cache/pip /root/.cache/pip
    COPY --from=builder /root/requirements.txt /root/requirements.txt
    
    RUN yum update -y && \
        yum install -y less groff jq python3-pip && \
        yum clean all && \
        pip3 install -r /root/requirements.txt && \
        rm -rf /root/.cache/pip
    
    RUN mkdir /root/.oci && \
        mkdir /usr/local/oci-cli
    
    COPY oci-cli.sh /usr/local/oci-cli/
    
    ENTRYPOINT ["/usr/local/oci-cli/oci-cli.sh"]
    
    많이 간소화되었지만 Fargate가 실행한 스크립트는 이렇습니다.
    #!/bin/bash
    # 環境変数からコンパートメントIDやシークレット名を取得
    readonly compartment=$COMPARTMENT
    readonly ociconfig=$OCICONFIG
    readonly ociapikey=$OCIAPIKEY
    readonly region="ap-tokyo-1"
    
    # configファイルと秘密鍵の取得
    aws secretsmanager get-secret-value \
      --secret-id "$ociconfig" \
      | jq -r .SecretBinary \
      | base64 --decode > /root/.oci/config
    
    aws secretsmanager get-secret-value \
      --secret-id "$ociapikey" \
      | jq -r .SecretBinary \
      | base64 --decode > /root/.oci/oci_api_key.pem
    
    chmod 400 /root/.oci/config
    chmod 400 /root/.oci/oci_api_key.pem
    
    # Object Storageのバケット一覧
    oci os bucket list \
      --compartment-id "$compartment" \
      --all \
      --region "$region"
    
    실제 환경에서 작업 역할에 S3의 권한을 분배하고 실행oci os object bulk-downloadaws s3 sync 등의 명령을 수행하는 스크립트를 배치하여 Object Storage에서 S3까지의 파일을 동기화한다.

    문외한: OCI 및 S3의 세그먼트 이름


    S3는 전역(모든 AWS 계정)에 유일한 이름을 붙여야 하지만, Object Storage에서는 OCI 계정 내(실제 배정된 이름 공간) 구역에서 유일하면 된다.
    사물의 발전에 대한 이해에서 인용하다.
    대상 진도는 모든 통과 대상의 용기입니다.이름 공간에서 세그먼트 이름을 제어하지만 세그먼트 이름은 각 세그먼트에서 고유해야 합니다.미국 서부(피닉스)에는 마이 버킷, 독일 중부(프랑크푸르트)에는 마이 버킷이라는 물통이 있다.
    통 이름에 관해서는 OCI가 더 유연한 것 같다.

    좋은 웹페이지 즐겨찾기