Do you use AWS CDK? I was using CFn, but writing in YAML has become a lot harder, so I recently switched to AWS CDK.
So, this time, I would like to write how to build an ECR using AWS CDK.
The following commands are installed
.
├── Pipfile
├── Pipfile.lock
├── README.md
├── app.py #CDK main script for Python
├── cdk.json #CDK config
├── cdk.out #CFn template etc. output from CDK is stored
├── mypy.ini
├── src
│ ├── __init__.py
│ ├── entity #Stores the entity of the resource
│ ├── props #Resource parameter definition class
│ └── stack #Store CFn stack
└── tox.ini
props/ -> entity/ -> stack/ -> app.py
By maintaining the above relationships, you will be more resistant to changes, and you can also manage by changing the parameters for each environment.
Install the required aws_cdk library
pipenv install aws_cdk.core aws_cdk.aws_ecr
props/ecr.py
The aws_cdk library for Python also has a Props class for each resource, but I personally feel that it is not easy to use, so I have defined it myself. Only the necessary parameters are set here, and the default value is changed from the official one depending on the application.
In the case of CFn, the life cycle rule must be written in JSON text, but in the case of CDK, it is quite easy because it only passes the value to the propadi.
from dataclasses import dataclass
from typing import Optional
from aws_cdk.aws_ecr import TagStatus
from aws_cdk.core import RemovalPolicy
from src.props.base import Base
@dataclass(frozen=True)
class LifecycleRule(Base):
description: Optional[str] = None
max_image_count: int = 5
rule_priority: int = 1
tag_status: TagStatus = TagStatus.ANY
@dataclass(frozen=True)
class Repository(Base):
id: str
repository_name: str
image_scan_on_push: Optional[bool] = None
removal_policy: RemovalPolicy = RemovalPolicy.RETAIN
entity/ecr.py
I will write the definition of the resource I want to create This time it is defined in a class, but I think you can instantiate it. I just do that because the class looks better personally
from typing import List, Optional
from src.entity.base import Base
from src.props.ecr import LifecycleRule, Repository
class EcrBase(Base):
"""ECR basis class"""
repository: Repository
lifecyle_rules: Optional[List[LifecycleRule]] = None
class SampleEcr(EcrBase):
"""Sample"""
id = 'SampleEcr'
repository = Repository(
id='SampleEcrRepo',
repository_name='sample'
)
lifecyle_rules = [
LifecycleRule(
description='Delete more than 10 images',
max_image_count=10
)
]
stack/ecr.py
We will define the stack for ECR The only resource definition you pass to the stack class should basically be ʻentity` After that, if necessary, let's pass the tag etc. that you want to set in common in app.py as an argument
from typing import Any, Type
from aws_cdk import core
from aws_cdk.aws_ecr import Repository
from src.entity.ecr import EcrBase
class EcrStack(core.Stack):
def __init__(
self,
scope: core.Construct,
entity: Type[EcrBase],
**kwargs: Any) -> None:
super().__init__(scope, entity.id, **kwargs)
repo = Repository(self, **entity.repository.to_dict())
if entity.lifecyle_rules:
for rule in entity.lifecyle_rules:
repo.add_lifecycle_rule(**rule.to_dict())
app.py
Let's write in app.py to deploy the stack written in stack / ecr.py
#!/usr/bin/env python3
from aws_cdk import core
from src.entity.ecr import SampleEcr
from src.stack.ecr import EcrStack
app = core.App()
#Tags to set for all resources
tags = {'CreatedBy': 'iscream'}
EcrStack(app, entity=SampleEcr, tags=tags)
app.synth(skip_validation=False)
There are two deployment methods:
pipenv run cdk deploy SampleEcr
OR
pipenv shell
cdk deploy SampleEcr
One thing to keep in mind when deploying is to run the cdk command on the virtual environment with pipenv. If you forget it, you will get the following error
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
In the case of CDK, resources can be defined in a programming language, so resources can be managed flexibly. On the other hand, if the code is not designed properly, it will become spaghetti, and it will be inflexible and difficult to operate. I don't know if the method introduced this time is the best practice, but I think that the operation will be improved just by managing directories and files separately for each function.
CDK is a pretty good product, so please try it !!
Reference
Recommended Posts