CDKでAWS Batch環境の作成 準備編

## 概要

CDKを使ってAWS環境を作成するときの方法についてまとめていこうと思います。
今回は準備編なので軽めに
(うまく動かないところがあったので・・・)

## 準備

* [AWS Summit](https://resources.awscloud.com/aws-summit-online-japan-2020-on-demand-self-paced-hands-on-85234)のCDKハンズオンを見て準備をしましょう。
* こちらでも簡単に準備手順を
    * AWS CLIのインストール 
    * AWS Configureの設定
        * アカウントはCDKで作成するリソースにアクセスできる権限を付与しましょう。(お試しでやる場合はAdministrator権限の方がいいかもしれません)
    * node.jsのインストール
    * `npm install -g aws-cdk` のコマンドでcdkをインストール

### プロジェクトの準備

* TypeScriptでの例となります。
1. 空のディレクトリを用意する。
1. ディレクトリに移動して以下のコマンドを実行する
    * `cdk init sample-app --language typescript`
1. 初期ディレクトリなどが作成されるのを待ちます。
1. 完了すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657697/edbe2421-1631-f316-f9f2-7c4b8c92d1d7.png)


## ライブラリのインストール
* 必要に応じて npm コマンドでライブラリをインストールします。以下のようなコマンドです。
    * `npm install @aws-cdk/aws-ecs`
    * `npm install @aws-cdk/aws-batch`
    * `npm install @aws-cdk/aws-ec2`
    * `npm install @aws-cdk/aws-iam`
    * `npm install @aws-cdk/aws-ecr`

## コンパイルの準備
* ライブラリインストール後にプロジェクトを作成したディレクトリに移動して以下のコマンドを実行します。windowsの場合はライブラリのインストール時には停止する必要があるので注意を
    * `npm run watch`

## 各ソースの説明
* ./lib/cdk-stack.ts
    * 各定義を作成する場所です。基本的にこのファイルを修正します
* ./bin/cdk.ts
    * 基本的には編集は不要ですが、VPCを使うときにID指定する場合以下の記述が必要になります。もともとある `new CdkStack(app, 'CdkStack'); `を書き換えます。
        * XXXXXXXXX はアカウントIDです。本番等では環境変数からとった方がよいです。

```typscript
    new CdkStack(app, 'CdkStack', {
    env: {
        region: 'ap-northeast-1',
        account: 'XXXXXXXXX',
    }
```

* ./package.json
    * インストール済みのライブラリが記載されています。バージョンなどが古くなっていないかの確認などを行いましょう。

### 現在作成中のCDKの定義

* VPCなどを指定する部分はIDを指定します。
* デプロイまではできましたが、インスタンスのロールの設定などがうまくいっていないので・・・

<details><summary>長いので折りたたんでます</summary><div>

```typescript
import * as cdk from '@aws-cdk/core';
import * as batch from '@aws-cdk/aws-batch';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import * as rds from '@aws-cdk/aws-rds';
import * as s3 from '@aws-cdk/aws-s3';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as iam from '@aws-cdk/aws-iam';
import * as ecs from '@aws-cdk/aws-ecs';
import * as ecr from '@aws-cdk/aws-ecr';
import { ContainerImage, EcrImage } from '@aws-cdk/aws-ecs';
import { Repository } from '@aws-cdk/aws-ecr';


export class CdkStack extends cdk.Stack {

  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {

    super(scope, id, props);
    
    // 既存のVPCを取得
    const vpc: ec2.IVpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: 'vpc-xxxxxxxxxxx',
    });
    // 既存のサブネットを取得
    const selectSubnets: ec2.SelectedSubnets = vpc.selectSubnets({
      subnets: [
        ec2.Subnet.fromSubnetAttributes(this, 'Subnet', {
          subnetId: 'subnet-xxxxxxxxxx',
          availabilityZone: 'ap-northeast-1a',
          routeTableId: 'rtb-xxxxxxxxxx',
        }),
      ]
    });

    // 既存のセキュリティーグループを取得
    const securityGroup: ec2.ISecurityGroup = ec2.SecurityGroup.fromSecurityGroupId(
      this, 'SecurityGroup', 'sg-xxxxxxxxx',
    );



    // バッチのロール
    const batchRole: iam.IRole = new iam.Role(this, 'BatchRole', {
      roleName: 'TestBatchRole',
      assumedBy: new iam.CompositePrincipal(
        new iam.ServicePrincipal('batch.amazonaws.com'),
      ),
      managedPolicies: [
        iam.ManagedPolicy.fromManagedPolicyArn(
          this,
          'AWSBatchServiceRole',
          'arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole',
        ),
      ],
    });


    // Job用ロールを作成
    const jobRole: iam.IRole = new iam.Role(this, 'JobRole', {
      roleName: 'TestJobRole',
      assumedBy: new iam.CompositePrincipal(
        new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
      ),
      managedPolicies: [
        iam.ManagedPolicy.fromManagedPolicyArn(
          this,
          'AmazonECSTaskExecutionRolePolicy',
          'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy',
        ),
      ],
    });


    // コンピューティング環境を作成 TODO ロールの設定ができていない
    const computeEnvironment: batch.ComputeEnvironment = new batch.ComputeEnvironment(this, 'BatchCompute', {
      computeEnvironmentName: 'TestComputeEnvironment',
      computeResources: {
        type: batch.ComputeResourceType.ON_DEMAND,
        vpc: vpc,
        vpcSubnets: selectSubnets,
        securityGroups: [securityGroup],
      },
      serviceRole:batchRole
    });

// 既存のリポジトリを指定
    const repository = Repository.fromRepositoryName(this,'pandastestRepo','pandastest2')

    const ecscontainerImage =  ecs.ContainerImage.fromEcrRepository( repository,'latest')
    
// 引数と環境変数を適当に設定 
    const jobDefinec = new batch.JobDefinition(this, 'JobDefinition', {
      jobDefinitionName: 'pandasTest',
      container: {
        command: ['1','3','A'],  
        environment: {'RDS_PASS': 'password','TEST':'ABC'},
        image: ecscontainerImage,
        jobRole: jobRole,
        vcpus: 1,
        memoryLimitMiB: 32,
      },
    });

  }
}




```
</div></details>