miniconda環境にlocalstack専用のenvironmentを作成する

localstack の実行環境を作成するにあたり、既存のPythonの環境とは分離しておきたいので、miniconda で localstack 専用の environment を作成して、ここにインストールした記録。

environment の作成

```
$ conda create -n localstack
Fetching package metadata .........
Solving package specifications: 
Package plan for installation in environment /Users/<username>/miniconda3/envs/localstack:

Proceed ([y]/n)? y
```

environment を activate

```
$ . activate localstack
(localstack) $
```

localstack をインストール。

```
(localstack) $ pip install localstack
```


localstack を起動

``` 
(localstack) $ localstack start
``` 


筆者の環境では以下のようなエラーが出て起動に失敗する状態だったため、つぎ示すようなパッチを当てた。

``` 
(localstack) $ localstack start
Starting local dev environment. CTRL-C to quit.
Error starting infrastructure: 'zipimport.zipimporter' object has no attribute 'path'
Traceback (most recent call last):
  File "/Users/<username>/miniconda3/envs/localstack/bin/localstack", line 79, in <module>
    infra.start_infra()
  File "/Users/<username>/miniconda3/envs/localstack/lib/python3.6/site-packages/localstack/services/infra.py", line 362, in start_infra
    raise e
  File "/Users/<username>/miniconda3/envs/localstack/lib/python3.6/site-packages/localstack/services/infra.py", line 308, in start_infra
    load_plugins()
  File "/Users/<username>/miniconda3/envs/localstack/lib/python3.6/site-packages/localstack/services/infra.py", line 102, in load_plugins
    file_path = '%s/%s/plugins.py' % (module[0].path, module[1])
AttributeError: 'zipimport.zipimporter' object has no attribute 'path'
```

`object has no attribute 'path'` の対策:

```
--- envs/localstack/lib/python3.6/site-packages/localstack/services/infra.py	2017-07-20 19:57:18.000000000 +0900
+++ envs/localstack/lib/python3.6/site-packages/localstack/services/infra.py	2017-07-20 20:22:30.000000000 +0900
@@ -96,7 +96,8 @@
         if six.PY3 and not isinstance(module, tuple):
             file_path = '%s/%s/plugins.py' % (module.module_finder.path, module.name)
         elif six.PY3 or isinstance(module[0], pkgutil.ImpImporter):
-            file_path = '%s/%s/plugins.py' % (module[0].path, module[1])
+            if hasattr(module[0], 'path'):
+                file_path = '%s/%s/plugins.py' % (module[0].path, module[1])
         if file_path and file_path not in loaded_files:
             load_plugin_from_path(file_path)
             loaded_files.append(file_path)
```


最初だけは立ち上がるまでかなり時間がかかるがじっと待つ。

```
(localstack) $ localstack start
Starting local dev environment. CTRL-C to quit.
Starting mock ES service (http port 4578)...
Starting local Elasticsearch (http port 4571)...
Starting mock S3 (http port 4572)...
Starting mock SNS (http port 4575)...
Starting mock SQS (http port 4576)...
Starting mock SES (http port 4579)...
Starting mock API Gateway (http port 4567)...
Starting mock DynamoDB (http port 4569)...
Starting mock DynamoDB Streams service (http port 4570)...
Starting mock Firehose service (http port 4573)...
Starting mock Lambda service (http port 4574)...
Starting mock Kinesis (http port 4568)...
Starting mock Redshift (http port 4577)...
Starting mock Route53 (http port 4580)...
Starting mock CloudFormation (http port 4581)...
Starting mock CloudWatch (http port 4582)...
WARNING:infra.py:Service "elasticsearch" not yet available, retrying...
WARNING:infra.py:Service "elasticsearch" not yet available, retrying...
WARNING:infra.py:Service "elasticsearch" not yet available, retrying...
Ready.
```


初期状態では、DynamoDB は `-inMemory` オプションがついた状態で起動され、localstack を停止するとデータも消滅する。
データを保存するためには、環境変数 `DATA_DIR` をセットしておく。
この環境変数をセットすると Kinesis と Elasticsearch のデータ保存場所もこのディレクトリの中に変更される。

conda 環境では、`activate` および `deactivate` を実行したときに、environment の `etc/conda/activate.d/*.sh` あるいは `etc/conda/deactivate.d/*.sh` が自動的に source されるので、自動的にこの環境変数をセットするようにフックを作成する。

ここでは、environment の data を `DATA_DIR` に指定している。

```
(localstack) $ cd $CONDA_PREFIX
(localstack) $ mkdir data
(localstack) $ mkdir -p etc/conda/activate.d
(localstack) $ mkdir -p etc/conda/deactivate.d
(localstack) $ echo 'export DATA_DIR=$CONDA_PREFIX/data' >etc/conda/activate.d/env_vars.sh
(localstack) $ echo 'unset DATA_DIR' >etc/conda/deactivate.d/env_vars.sh
```

いったん deactivate して、再度 activate すれば、環境変数 `DATA_DIR` がセットされているはずである。

```
(localstack) $ . deactivate
$ . activate localstack
(localstack) $ echo $DATA_DIR
/Users/<username>/miniconda3/envs/localstack/data
```

この状態で localstack を起動すれば、DynamoDB のデータも localstack の停止後も消えずに残るようになる。


プロキシを使用するように環境変数 `http_proxy` (または `HTTP_PROXY`) が設定されている環境では、以下のように elasticsearch の起動チェックで、何度か `WARNING:infra.py:Service "elasticsearch" not yet available, retrying...` の警告が出た後、エラーで終了することがある。
これは、起動チェックでモックサーバに接続しに行くところがプロキシサーバ経由となり、モックサーバに接続できないことが原因である。
このような場合、プロキシサーバを使用しないように環境変数の設定を解除すればエラーは解消するはずである。

```
WARNING:infra.py:Service "elasticsearch" not yet available, retrying...
ERROR:localstack.services.es.es_starter:Elasticsearch health check failed (retrying...): (以降略)
```