Config Management Code Recipe (CN)#
示例代码的背景信息请参考 Centralized Multi Environment Config Management (CN).
Declare your Config Schema#
aws_ops_alpha
提供了一些工具方便你定义你的 Multi environment Config 对象. 下面是一个例子.
[5]:
# config/define.py module
import typing as T
import dataclasses
from functools import cached_property
# import aws_ops_alpha
from aws_ops_alpha.api import (
BaseEnv,
BaseConfig,
)
# split your config field into groups, declare them in different mixin class,
# then you can assemble them together.
# it can improve your code maintainability.
@dataclasses.dataclass
class AppMixin:
username: T.Optional[str] = dataclasses.field(default=None)
password: T.Optional[str] = dataclasses.field(default=None)
@dataclasses.dataclass
class Env(
AppMixin,
BaseEnv,
):
pass
# Create a reference property to access per-environment config data
@dataclasses.dataclass
class Config(BaseConfig[Env]):
@classmethod
def get_current_env(cls) -> str: # pragma: no cover
return detect_current_env()
@cached_property
def sbx(self): # pragma: no cover
return self.get_env(env_name="sbx")
@cached_property
def tst(self) -> Env: # pragma: no cover
return self.get_env(env_name="tst")
@cached_property
def prd(self) -> Env: # pragma: no cover
return self.get_env(env_name="prd")
@cached_property
def env(self) -> Env:
return self.get_env(env_name=self.get_current_env())
Load Your Config Data.#
aws_ops_alpha
提供了一套储存 Config 数据的最佳实践. 如果你使用了这套最佳实践, 你可以直接用 Config.smart_load
方法来读取 config 对象.
这套储存 Config 数据的最佳实践的详细规则如下.
如果是在 local 本地开发 Runtime 下, 则从
path_config_json
(储存了非敏感 Config 数据, 通常就在 git repo 里面),path_config_secret_json
(储存了敏感数据, 通常在${HOME}
目录下).如果是在 CI Runtime 下, 则会先从 Git repo 中的
path_config_json
读取一部分数据. 目的是为了根据project_name
计算出parameter_name
的值, 然后根据这个值到 AWS Parameter Store 获得 Config 数据. 因为project_name
不是敏感数据, 所以这里我们不需要path_config_secret_json
, 并且我们也不允许将敏感数据放在 CI 环境中.如果是在 App 的 Runtime 下, 则先读取
PARAMETER_NAME
环境变量的值, 然后根据这个值到 AWS Parameter Store 获得 Config 数据.
以下是一个使用了这套最佳实践的真实项目的代码示例.
[ ]:
# config/load.py module
config = Config.smart_load(
runtime=runtime,
env_name_enum_class=EnvNameEnum,
env_class=Env,
path_config_json=paths.path_config_json,
path_config_secret_json=paths.path_config_secret_json,
boto_ses_factory=boto_ses_factory,
)
如果你希望自定义 Config loading 的方式, 你可以自己手动实现. 下面是一段手动实现 Config 读取的示例代码.
[13]:
from aws_ops_alpha.api import (
BaseEnvNameEnum,
)
class EnvNameEnum(BaseEnvNameEnum):
devops = "devops"
sbx = "sbx"
tst = "tst"
prd = "prd"
config = Config(
data={
"_shared": {
"*.project_name": "simple_lambda",
"*.s3uri_artifacts": "s3://bmt-app-devops-us-east-1-artifacts/projects/monorepo_aws/simple_lambda/",
"*.s3uri_docs": "s3://bmt-app-devops-us-east-1-doc-host/projects/monorepo_aws/",
},
"devops": {
"s3uri_data": "s3://bmt-app-devops-us-east-1-data/projects/simple_lambda/"
},
"sbx": {
"username": "sbx.user",
"s3uri_data": "s3://bmt-app-dev-us-east-1-data/projects/simple_lambda/"
},
"tst": {
"username": "tst.user",
"s3uri_data": "s3://bmt-app-test-us-east-1-data/projects/simple_lambda/"
},
"prd": {
"username": "prd.user",
"s3uri_data": "s3://bmt-app-prod-us-east-1-data/projects/simple_lambda/"
}
},
secret_data={
"_shared": {},
"devops": {},
"sbx": {
"password": "sbx.password"
},
"tst": {
"password": "tst.password"
},
"prd": {
"password": "prd.password"
}
},
Env=Env,
EnvEnum=EnvNameEnum,
version="1",
)
[16]:
config.sbx.username
[16]:
'sbx.user'
[17]:
config.sbx.password
[17]:
'sbx.password'
[19]:
config.sbx.s3uri_artifacts
[19]:
's3://bmt-app-devops-us-east-1-artifacts/projects/monorepo_aws/simple_lambda/'
[ ]: