IBM Cloud Schematics を使って IBM Cloud Object Storage (ICOS) に直接ファイルダウンロード


# 概要
サイズが大きいイメージファイルなどを IBM Cloud Object Storage (ICOS) に直接ファイルダウンロードしたいことがあります。
一旦、ローカルPCにダウンロードしてから IBM Cloud Object Storage (ICOS) にアップロードすると、ローカルPCが接続された回線にも依存し、時間がかかることがあります。
今回は、URL 先のファイルをローカルPCに保存せず IBM Cloud Object Storage (ICOS) に直接ファイルダウンロードする機能を IBM Cloud Schematics (Terraform as a Service) の local-exec provider を使って実装します。

# CLI プラグインインストール
事前に CLI プラグインをインストールします。

```shell

ibmcloud plugin install schematics
ibmcloud plugin show schematics
```

# GitHub からダウンロード
GitHub にあるファイルをダウンロードします。

>[khayama/schematics-local-exec-dl2cos](https://github.com/khayama/schematics-local-exec-dl2cos)

```shell

git clone https://github.com/khayama/schematics-local-exec-dl2cos.git
cd schematics-local-exec-dl2cos 
```

# Schematics Workspace の作成
JSON ファイルを使って、 Schematics Workspace を作成します。
`variable` は後ほど変更できます。

```shell

ibmcloud schematics workspace new --file config.json
```

```json:config.json
{
  "name": "khayama-local-exec-dl2cos",
  "type": [
    "terraform_v0.12"
  ],
  "description": "",
  "tags": ["owner:khayama"],
  "resource_group": "khayama-rg",
  "workspace_status": {
    "frozen": false
  },
  "template_repo": { 
    "url": "https://github.com/khayama/schematics-local-exec-dl2cos.git"
  },
  "template_data": [
    {
      "folder": ".",
      "type": "terraform_v0.12",
      "variablestore": [
        {
          "name": "bucket_name",
          "value": "khayama-icos",
          "type": "string",
          "secure": false
        },
        {
          "name": "endpoint",
          "value": "s3.jp-tok.cloud-object-storage.appdomain.cloud",
          "type": "string",
          "secure": false
        },
        {
          "name": "url",
          "value": "http://ipv4.download.thinkbroadband.com/5MB.zip",
          "type": "string",
          "secure": false
        }
      ]
    }
  ],
  "githubtoken": ""
}
```

# Variables 変更
こちらの画面から、パラメータを設定します。
https://cloud.ibm.com/schematics/workspaces

![貼り付けた画像_2020_06_12_16_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/62dc5431-5f02-10e6-8d01-444f3d6ffe44.png "貼り付けた画像_2020_06_12_16_25.png")

# Apply Plan 実行
正常に実行された場合は、以下のようなログが確認できます。

```
 2020/06/12 05:45:29 Terraform apply | null_resource.curl (local-exec): curl 7.64.0 (x86_64-pc-linux-gnu) libcurl/7.64.0 OpenSSL/1.1.1d zlib/1.2.11 libidn2/2.0.5 libpsl/0.20.2 (+libidn2/2.0.5) libssh2/1.8.0 nghttp2/1.36.0 librtmp/2.3
 ...
 2020/06/12 05:45:29 Terraform apply | null_resource.curl (local-exec): basename is 5MB.zip
 ...
 2020/06/12 05:45:30 Terraform apply | null_resource.curl (local-exec): content-type is application/zip
 ...
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): 2020-06-12 05:45:37 URL:http://ipv4.download.thinkbroadband.com/5MB.zip [5242880/5242880] -> "5MB.zip" [1]
 ...
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): total 5156
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rw-r--r-- 1 appuser appuser 5242880 Jun  2  2008 5MB.zip
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rwxr-xr-x 1 appuser appuser     946 Jun 12 05:45 config.json
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rw------- 1 appuser appuser   10240 Jun 12 05:45 fullrepo.tar
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): drwx------ 2 appuser appuser    4096 Jun 12 05:45 khayama-local-exec-dl2cos530181810
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rwxr-xr-x 1 appuser appuser    3193 Jun 12 05:45 resource.tf
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rwxr-xr-x 1 appuser appuser     145 Jun 12 05:45 schematics.tfvars
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rwxr-xr-x 1 appuser appuser       0 Jun 12 05:45 terraform-secret-env
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rwxr-xr-x 1 appuser appuser     158 Jun 12 05:45 terraform.tfstate
 2020/06/12 05:45:37 Terraform apply | null_resource.curl (local-exec): -rw-r--r-- 1 appuser appuser     567 Jun 12 05:45 terraform.tfstate.backup
 ...
  2020/06/12 05:45:39 Terraform apply | null_resource.curl (local-exec): * We are completely uploaded and fine
 ...
```

![貼り付けた画像_2020_06_12_16_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/105d656b-6a34-dab7-cbb6-be6dde577c8e.png "貼り付けた画像_2020_06_12_16_40.png")


# `local-exec` の中身

- Apply するごとに local-exec の処理がおこなわれるようにしています
- Schematics 実行コンテナ環境で環境変数 `$IC_IAM_TOKEN` が自動的にセットされるので、各アカウントでの認証に使っています

```terraform:resource.tf

resource "null_resource" "dl2cos" {

  triggers = {
    always_run = "${timestamp()}"
  }

  provisioner "local-exec" {
    command =<<EOT
      curl --version
      object_name=$(basename ${var.url})
      echo "basename is $object_name"
      content_type=$(curl -sI ${var.url} -w '%%{content_type}\n' -o /dev/null)
      echo "content-type is $content_type"
      filename=$(curl -sI ${var.url} | grep "Content-Disposition" | cut -d \" -f 2)
      echo "filename is $filename"
      if [ -n "$filename" ]; then
        object_name="$filename"
      fi
      wget -O $object_name -nv --no-check-certificate ${var.url} -P $PWD
      if [ $? -ne 0 ]; then
        echo "[ERROR] 正常にダウンロードできませんでした"
        exit 1
      fi
      ls -l
      curl -v -X PUT https://${var.bucket_name}.${var.endpoint}/$object_name -H "Authorization: Bearer $IC_IAM_TOKEN" -H "Content-Type: $content_type" -T $object_name
    EOT
  }
}
```

# 参考
- [【Terraform】template_fileにてshellで変数を使う方法 - Qiita](https://qiita.com/akahori_s/items/8060a1f151ccd5a0f290)
- [How to always run local-exec with Terraform](https://ilhicas.com/2019/08/17/Terraform-local-exec-run-always.html)
- [CLI command reference](https://cloud.ibm.com/docs/schematics?topic=schematics-schematics-cli-reference)
- [Using cURL](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-curl)
- [[Linux] Bashでwgetの戻り値をチェックする](https://blog.katsubemakito.net/linux/bash-wget-return)

# 参考コマンド

## Workspace Name & ID の格納

```
workspace_name=`cat config.json | jq -r .name`
workspace_id=`ibmcloud schematics workspace list --json | jq -r '.[]' | jq -r '.[] | select (.name=="'$workspace_name'") | .id'`
```

## config.json の修正

```
vi config.json
git commit -am "Update" && git push
```

## Schematics Workspace 操作

```
ibmcloud schematics workspace update --id $workspace_id --file config.json
ibmcloud schematics apply -f --id $workspace_id
ibmcloud schematics logs --id $workspace_id
ibmcloud schematics destroy -f --id $workspace_id
```