はじめに
Pythonを書いたことのない初心者が、テキストで書いていたCloudformationをCDKでやってねと言われたときの話。
注意
この記事はAWSの公式を感想を交えてなぞ(って検証す)るだけの記録です。
英語の記事はGoogle翻訳を使います。
CDK
ぐぐったらすぐに見つかりました。
既存のCloudFormationテンプレートファイルをAWS CDKに移行してみた(dev.classmethod.jp)
すぐに記事のマネをしたい気になりましたが一呼吸。
「ググるのをやめるとプログラムの生産性が上がるかもしれない(simplearchitect.hatenablog.com)」を思い出して、まず公式ドキュメントを探します。
こちらもすぐに見つかりましたが、イングリッシュ!
Getting started with the AWS CDK
ですが諦めてガイドをいちから取り組みます。
What is the AWS CDK?
コードでかけるよ、と追加のドキュメント。
Getting started with the AWS CDK
GoかPythonで書いてねと聞いていましたが、5つの言語(TypeScript, JavaScript, Python, Java, or C#)から選べるようです。
あれ?Goがない?
「Finally, you should be proficient in the programming language you intend to use with the AWS CDK.」
スクリプト書きますがBashとコマンドプロンプトしか書きません。
習熟が必要なんて最初に言って欲しいですね。
とはいえ、5つから選び放題というのも贅沢な悩みです。
出てきた用語。
アップ、スタック(Cloudformationと同じ単語だけど指しているものは違う?)、コンストラクト。
アップ内にスタックがあって、スタック内にコンストラクトがあって、コンストラクトの中にAWSリソースが定義される。
コンストラクトは3つにわかれる。(L1 ... Level 1)
・AWS CloudFormation-only or L1→Cfnに直接対応。
・Curated or L2→L1をカプセル化?
・Patterns or L3→コンストラクトライブラリではL1/L2とは別…(意味不)
Node.jsが必要? Javascriptの実行環境くらいの知識で、完全に異国のツール状態です。
なんとなく brew install node.js
と打ってみたら入りました。
% which -a node
/usr/local/bin/node
% node -v
v15.4.0
awsのクレデンシャルを入力します。
aws configure --profile cdktest
% npm install -g aws-cdk
added 192 packages, and audited 192 packages in 6s
found 0 vulnerabilities
npm notice
npm notice New minor version of npm available! 7.0.15 -> 7.1.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v7.1.1
npm notice Run npm install -g npm@7.1.1 to update!
npm notice
% cdk --version
1.77.0 (build a941c53)
次に進みます。
Your first AWS CDK app
プロジェクト用のフォルダを作ります。
% mkdir hello-cdk
% cd hello-cdk
% cdk init app --language python
ドキュメントと実行する内容が少し違いました。
% source .venv/bin/activate
入力の際に(.venv)
と付くようになりました。
(.venv)% python -m pip install -r requirements.txt
2行目を見るとpipで警告が出ていたのでアップデートします。
WARNING: You are using pip version 20.2.1; however, version 20.3.1 is available.
You should consider upgrading via the '/Users/myname/hello-cdk/.venv/bin/python -m pip install --upgrade pip' command.
(.venv)% /Users/myname/hello-cdk/.venv/bin/python -m pip install --upgrade pip
Collecting pip
Downloading pip-20.3.1-py2.py3-none-any.whl (1.5 MB)
|████████████████████████████████| 1.5 MB 5.8 MB/s
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.2.1
Uninstalling pip-20.2.1:
Successfully uninstalled pip-20.2.1
Successfully installed pip-20.3.1
スタック一覧を見ます。
(.venv)% cdk ls
hello-cdk
S3バケットのリソースが入ったスタックをまず作るようです。
コンストラクトライブラリから、AmazonS3パッケージをインストールします。
必要なサービスはこの「コンストラクトライブラリ」からDLすつ必要があるようです。
(.venv)% pip install aws-cdk.aws-s3
Collecting aws-cdk.aws-s3
(中略)
Installing collected packages: aws-cdk.aws-iam, aws-cdk.aws-kms, aws-cdk.aws-events, aws-cdk.aws-s3
Successfully installed aws-cdk.aws-events-1.77.0 aws-cdk.aws-iam-1.77.0 aws-cdk.aws-kms-1.77.0 aws-cdk.aws-s3-1.77.0
hello_cdk/hello_cdk_stack.pyを2箇所書き換えよと出ています。
変更前の中身をみてみます。
(.venv)% cat -n hello_cdk/hello_cdk_stack.py
1 from aws_cdk import core
2
3
4 class HelloCdkStack(core.Stack):
5
6 def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
7 super().__init__(scope, construct_id, **kwargs)
8
9 # The code that defines your stack goes here
指示が曖昧ですが書き換えてみます。
pythonもコメントアウトは#でできる模様。インデントが意味を持つ言語と聞いていたので、とりあえず行頭、行頭でないを守ってコピペしてみます。
(.venv)% cat -n hello_cdk/hello_cdk_stack.py
1 #from aws_cdk import core
2 from aws_cdk import (
3 aws_s3 as s3,
4 core as cdk
5 )
6
7 class HelloCdkStack(core.Stack):
8
9 def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
10 super().__init__(scope, construct_id, **kwargs)
11
12 # The code that defines your stack goes here
13 bucket = s3.Bucket(self,
14 "MyFirstBucket",
15 versioned=True,)
こんな理解でしょうか。
パラメーター | 内容 |
---|---|
scope | self |
Id | "MyFirstBucket" |
props | versioned=True |
検索するとCDKのクラスが出てきました。
class Bucket (construct)(docs.aws.amazon.com)
シンセサイズしてみます。
(.venv)% cdk synth
Traceback (most recent call last):
File "app.py", line 5, in <module>
from hello_cdk.hello_cdk_stack import HelloCdkStack
File "/Users/myname/hello-cdk/hello_cdk/hello_cdk_stack.py", line 7, in <module>
class HelloCdkStack(core.Stack):
NameError: name 'core' is not defined
Subprocess exited with error 1
coreがないと怒られます。
1行目はコメントアウトしてはいけなかったんでしょうか。
1行目のコメントアウトを外してみます。
(.venv)% cat -n hello_cdk/hello_cdk_stack.py | head -n 2
1 from aws_cdk import core
2 from aws_cdk import (
(.venv)% cdk synth
Traceback (most recent call last):
File "app.py", line 5, in <module>
from hello_cdk.hello_cdk_stack import HelloCdkStack
File "/Users/myname/hello-cdk/hello_cdk/hello_cdk_stack.py", line 13, in <module>
bucket = s3.Bucket(self,
NameError: name 'self' is not defined
Subprocess exited with error 1
今度はselfが無いと…
詰んだ感じので、README.mdを見ます。
見ると、いくつかコマンドがあるようです。
* `cdk ls` list all stacks in the app
* `cdk synth` emits the synthesized CloudFormation template
* `cdk deploy` deploy this stack to your default AWS account/region
* `cdk diff` compare deployed stack with current state
* `cdk docs` open CDK documentation
Diffができるようです。
(.venv)% cdk diff
Traceback (most recent call last):
File "app.py", line 5, in <module>
from hello_cdk.hello_cdk_stack import HelloCdkStack
File "/Users/myname/hello-cdk/hello_cdk/hello_cdk_stack.py", line 13, in <module>
bucket = s3.Bucket(self,
NameError: name 'self' is not defined
Subprocess exited with error 1
同じように出てしまいます。
ぐぐると、インデントの可能性が高そうです。
def init と同じところにbucketがくるようにします。
(.venv)% cat -n hello_cdk/hello_cdk_stack.py
1 from aws_cdk import core
2 from aws_cdk import (
3 aws_s3 as s3,
4 core as cdk
5 )
6
7 class HelloCdkStack(core.Stack):
8
9 def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
10 super().__init__(scope, construct_id, **kwargs)
11
12 # The code that defines your stack goes here
13 bucket = s3.Bucket(self,
14 "MyFirstBucket",
15 versioned=True,)
なしてdiffを…
(.venv)% cdk diff
Traceback (most recent call last):
File "app.py", line 5, in <module>
from hello_cdk.hello_cdk_stack import HelloCdkStack
File "/Users/myname/hello-cdk/hello_cdk/hello_cdk_stack.py", line 7, in <module>
class HelloCdkStack(core.Stack):
File "/Users/myname/hello-cdk/hello_cdk/hello_cdk_stack.py", line 13, in HelloCdkStack
bucket = s3.Bucket(self,
NameError: name 'self' is not defined
Subprocess exited with error 1
またエラーが出ました。ううむ…
コメントと同じインデントにしてみます。
(.venv)% cat -n hello_cdk/hello_cdk_stack.py
1 from aws_cdk import core
2 from aws_cdk import (
3 aws_s3 as s3,
4 core as cdk
5 )
6
7 class HelloCdkStack(core.Stack):
8
9 def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
10 super().__init__(scope, construct_id, **kwargs)
11
12 # The code that defines your stack goes here
13 bucket = s3.Bucket(self,
14 "MyFirstBucket",
15 versioned=True,)
(.venv)% cdk diff
Stack hello-cdk
Conditions
[+] Condition CDKMetadata/Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-northwest-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"sa-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]}]}
Resources
[+] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
おお、通りました。
def __init__
のところでselfが定義されていて、そのインデントよりも下(深い?)にないと、selfが使えなかったのかもしれません。
synthしてみます。
(.venv)% cdk synth
Resources:
MyFirstBucketB8884501:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
Metadata:
aws:cdk:path: hello-cdk/MyFirstBucket/Resource
CDKMetadata:
Type: AWS::CDK::Metadata
Properties:
Modules: aws-cdk=1.77.0,@aws-cdk/aws-events=1.77.0,@aws-cdk/aws-iam=1.77.0,@aws-cdk/aws-kms=1.77.0,@aws-cdk/aws-s3=1.77.0,@aws-cdk/cloud-assembly-schema=1.77.0,@aws-cdk/core=1.77.0,@aws-cdk/cx-api=1.77.0,@aws-cdk/region-info=1.77.0,jsii-runtime=Python/3.8.6
Metadata:
aws:cdk:path: hello-cdk/CDKMetadata/Default
Condition: CDKMetadataAvailable
Conditions:
CDKMetadataAvailable:
Fn::Or:
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- ap-east-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-northeast-2
- Fn::Equals:
- Ref: AWS::Region
- ap-south-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-1
- Fn::Equals:
- Ref: AWS::Region
- ap-southeast-2
- Fn::Equals:
- Ref: AWS::Region
- ca-central-1
- Fn::Equals:
- Ref: AWS::Region
- cn-north-1
- Fn::Equals:
- Ref: AWS::Region
- cn-northwest-1
- Fn::Equals:
- Ref: AWS::Region
- eu-central-1
- Fn::Or:
- Fn::Equals:
- Ref: AWS::Region
- eu-north-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-1
- Fn::Equals:
- Ref: AWS::Region
- eu-west-2
- Fn::Equals:
- Ref: AWS::Region
- eu-west-3
- Fn::Equals:
- Ref: AWS::Region
- me-south-1
- Fn::Equals:
- Ref: AWS::Region
- sa-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-1
- Fn::Equals:
- Ref: AWS::Region
- us-east-2
- Fn::Equals:
- Ref: AWS::Region
- us-west-1
- Fn::Equals:
- Ref: AWS::Region
- us-west-2
めちゃくちゃ長いファイルができました。多少見慣れたファイルで安心します。
S3のMyFirstBucketB8884501の数字はどこから出てきたんでしょう。
cdk synth
というコマンドが、アプリ実行のようです。
先程指定したリソースが、テンプレートとして出力されるようです。
スタックを.pyファイルで作成すれば良いのでしょうか。
デプロイしてみます。
(.venv)% cdk deploy
hello-cdk: deploying...
hello-cdk: creating CloudFormation changeset...
[██████████████████████████████████████████████████████████] (3/3)
✅ hello-cdk
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/hello-cdk/f75ee690-3ba0-11eb-b1cf-0611461e9ae4
デプロイされました。
今度はバケットに変更を加えるようです。
パブリック読み取り→有効
スタック削除でバケットの自動削除→有効
(.venv)% cat -n hello_cdk/hello_cdk_stack.py
1 from aws_cdk import core
2 from aws_cdk import (
3 aws_s3 as s3,
4 core as cdk
5 )
6
7 class HelloCdkStack(core.Stack):
8
9 def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
10 super().__init__(scope, construct_id, **kwargs)
11
12 # The code that defines your stack goes here
13 bucket = s3.Bucket(self,
14 "MyFirstBucket",
15 versioned=True,
16 public_read_access=True,
17 removal_policy=cdk.RemovalPolicy.DESTROY)
せっかくなのでdiffしてみます。
(.venv)% cdk diff
Stack hello-cdk
IAM Statement Changes
┌───┬────────────────────────┬────────┬──────────────┬───────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼────────────────────────┼────────┼──────────────┼───────────┼───────────┤
│ + │ ${MyFirstBucket.Arn}/* │ Allow │ s3:GetObject │ * │ │
└───┴────────────────────────┴────────┴──────────────┴───────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Resources
[+] AWS::S3::BucketPolicy MyFirstBucket/Policy MyFirstBucketPolicy3243DEFD
[~] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
├─ [~] DeletionPolicy
│ ├─ [-] Retain
│ └─ [+] Delete
└─ [~] UpdateReplacePolicy
├─ [-] Retain
└─ [+] Delete
めっちゃ見やすい…
deployしてみます。
diffではリソースの変化も出ましたが、deployではリソースの変化は表示されず、IAMポリシーの表示だけでした。
(.venv)% cdk deploy
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:
IAM Statement Changes
┌───┬────────────────────────┬────────┬──────────────┬───────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼────────────────────────┼────────┼──────────────┼───────────┼───────────┤
│ + │ ${MyFirstBucket.Arn}/* │ Allow │ s3:GetObject │ * │ │
└───┴────────────────────────┴────────┴──────────────┴───────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Do you wish to deploy these changes (y/n)? y
hello-cdk: deploying...
hello-cdk: creating CloudFormation changeset...
[██████████████████████████████████████████████████████████] (3/2)
✅ hello-cdk
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/hello-cdk/f75ee690-3ba0-11eb-b1cf-0611461e9ae4
大きなスタックの差分としては2つ
1つ目は「UpdateReplacePolicy」と「DeletionPolicy」がRetain(残す)から、Deleteに変わっていました。
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
removal_policy=cdk.RemovalPolicy.DESTROY
という行に当たるようです。
cdk.RemovalPolicy.DESTROYはどこで定義されているんでしょうか…
宣言のところでcore as cdk
とあり、cdkをcoreと読み替えるようなので、
coreというクラスがありそうです。
enum RemovalPolicy(docs.aws.amazon.com)にありました。
2つ目はポリシーの追加。
MyFirstBucketPolicy3243DEFD:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: MyFirstBucketB8884501
PolicyDocument:
Statement:
- Action: s3:GetObject
Effect: Allow
Principal: "*"
Resource:
Fn::Join:
- ""
- - Fn::GetAtt:
- MyFirstBucketB8884501
- Arn
- /*
Version: "2012-10-17"
Metadata:
aws:cdk:path: hello-cdk/MyFirstBucket/Policy/Resource
最後にクイックツアーを終了するのにスタックリソースを削除します。
何が消えるか・・・はわかりません。
(.venv)% cdk destroy
Are you sure you want to delete: hello-cdk (y/n)? y
hello-cdk: destroying...
9:32:47 PM | DELETE_IN_PROGRESS | AWS::CloudFormation::Stack | hello-cdk
9:32:50 PM | DELETE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default
✅ hello-cdk: destroyed
スタックが削除されました。
terminalを開き直して、cdk diffを実施しても環境変数がない状態だとエラーが出ます。
% cdk diff
Traceback (most recent call last):
File "app.py", line 3, in <module>
from aws_cdk import core
ModuleNotFoundError: No module named 'aws_cdk'
Subprocess exited with error 1
README.mdのとおりに環境変数を設定するときちんと差分が見えます。
% source .venv/bin/activate
(.venv)% cdk diff
Stack hello-cdk
IAM Statement Changes
┌───┬────────────────────────┬────────┬──────────────┬───────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼────────────────────────┼────────┼──────────────┼───────────┼───────────┤
│ + │ ${MyFirstBucket.Arn}/* │ Allow │ s3:GetObject │ * │ │
└───┴────────────────────────┴────────┴──────────────┴───────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Conditions
[+] Condition CDKMetadata/Condition CDKMetadataAvailable: {"Fn::Or":[{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-northeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ap-southeast-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"ca-central-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"cn-northwest-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-central-1"]}]},{"Fn::Or":[{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-north-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"eu-west-3"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"me-south-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"sa-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-east-2"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-1"]},{"Fn::Equals":[{"Ref":"AWS::Region"},"us-west-2"]}]}]}
Resources
[+] AWS::S3::Bucket MyFirstBucket MyFirstBucketB8884501
[+] AWS::S3::BucketPolicy MyFirstBucket/Policy MyFirstBucketPolicy3243DEFD
環境変数をみてみます。
(.venv)% cat .venv/bin/activate
# This file must be used with "source bin/activate" *from bash*
# you cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
if [ ! "${1:-}" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
VIRTUAL_ENV="/Users/myname/hello-cdk/.venv"
export VIRTUAL_ENV
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
if [ "x(.venv) " != x ] ; then
PS1="(.venv) ${PS1:-}"
else
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then
# special case for Aspen magic directories
# see https://aspen.io/
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1"
else
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1"
fi
fi
export PS1
fi
# This should detect bash and zsh, which have a hash command that must
# be called to get it to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
hash -r
fi
意外と長い。
VIRTUAL_ENV、PYTHONHOME、PS1、というあたりをセットしているようです。
スタックの作成、削除ができたのでチュートリアルは終了します。
リファレンス