简介
在这个快速指南中,我将向你展示如何使用Python AWS CDK应用程序来自动部署和配置你的Apache Airflow环境,在AWS上使用Apache Airflow的管理工作流程(MWAA)。
你将需要什么:
- 一个具有正确权限的AWS账户
- 一个配置并运行AWS CDK的开发环境(在撰写本文时,你应该使用AWS CDK v2)。
- 访问支持Apache Airflow的托管工作流的AWS区域
- 本指南中使用的所有代码都在这个GitHub仓库中提供。
一些需要注意的事情:
- 如果你在一个已经有VPC的环境中部署,如果你超过了你的AWS账户中的VPC数量,你可能会产生一个错误(默认情况下,这被设置为5,但这是个软限制,你可以申请增加)。
- 在运行CDK应用程序之前,请确保你为MWAA环境定义的Amazon S3桶不存在。
入门
确保我们正在运行正确版本的AWS CDKv2工具(至少是v2.2),然后查看git repo。
Shell
cdk --version
> 2.28.1 (build d035432)
git clone https://github.com/094459/blogpost-cdk-mwaa.git
在检查完资源库后,你将在你的本地开发环境中拥有以下文件。
纯文本
├── app.py
├── cdk.json
├── dags
│ ├── sample-cdk-dag-od.py
│ └── sample-cdk-dag.py
├── mwaa_cdk
│ ├── mwaa_cdk_backend.py
│ └── mwaa_cdk_env.py
└── requirements.txt
我们需要做的第一件事是更新我们的Python依赖项,这些依赖项在requirements.txt文件中被记录下来。
注意!如果你目前正在使用在AWS CDKv1和v2之间的移动过程中,那么你应该看看这篇博文,帮助你做好准备,因为后面的步骤可能会失败。
Shell
pip install -r requirements.txt
探索CDK栈
我们的AWS CDK应用程序由一些文件组成。我们应用程序的入口是app.py文件,在这里我们定义了我们要建立的结构和资源。然后我们有两个CDK堆栈来部署和配置AWS资源。最后,我们有资源,我们将其部署到我们的目标Apache Airflow环境。
如果我们看一下app.py 文件,我们可以看到更详细地探索我们的CDK应用。我们正在创建两个堆栈,一个叫mwaa_cdk_backend ,另一个叫mwaa_cdk_env 。
mwaa_cdk_backend 将被用来设置MWAA环境要使用的VPC网络。mwaa_cdk_env 是将配置你的MWAA环境的堆栈。
为了做到这一点,首先,我们要设置一些配置参数,以便我们能够最大限度地重复使用这个CDK应用程序
Shell
import aws_cdk as cdk
from mwaa_cdk.mwaa_cdk_backend import MwaaCdkStackBackend
from mwaa_cdk.mwaa_cdk_env import MwaaCdkStackEnv
env_EU=cdk.Environment(region="{your-aws-region}", account="{your-aws-ac}")
mwaa_props = {'dagss3location': '{your-unqiue-s3-bucket}','mwaa_env' : '{name-of-your-mwaa-env}'}
app = cdk.App()
mwaa_hybrid_backend = MwaaCdkStackBackend(
scope=app,
id="mwaa-hybrid-backend",
env=env_EU,
mwaa_props=mwaa_props
)
mwaa_hybrid_env = MwaaCdkStackEnv(
scope=app,
id="mwaa-hybrid-environment",
vpc=mwaa_hybrid_backend.vpc,
env=env_EU,
mwaa_props=mwaa_props
)
app.synth()
我们在env_EU 和mwaa_props 行中定义配置参数。这将使你能够重新使用这个堆栈来创建多个不同的环境。如果你想让其他配置选项可以通过配置属性来改变,你也可以在mwaa_props中添加/改变这些变量(例如,日志口令或可能是Apache Airflow的版本)。
在改变 app.py 文件中的值并保存后,我们就可以部署了。
淘宝网
除了创建MWAA所需的底层网络基础设施外,这并没有什么特别有趣的地方。你不需要做什么,但如果你确实想做实验,那么我要说的是:a)确保你阅读并遵循MWAA文档网站上的网络指导,因为他们为你提供了需要设置的细节;b)如果你试图锁定网络,试着只部署后端堆栈,然后手动创建一个MWAA环境,看看它是否工作/失败了。
Shell
from aws_cdk import (
aws_iam as iam,
aws_ec2 as ec2,
Stack,
CfnOutput
)
from constructs import Construct
class MwaaCdkStackBackend(Stack):
def __init__(self, scope: Construct, id: str, mwaa_props, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# Create VPC network
self.vpc = ec2.Vpc(
self,
id="MWAA-Hybrid-ApacheAirflow-VPC",
cidr="10.192.0.0/16",
max_azs=2,
nat_gateways=1,
subnet_configuration=[
ec2.SubnetConfiguration(
name="public", cidr_mask=24,
reserved=False, subnet_type=ec2.SubnetType.PUBLIC),
ec2.SubnetConfiguration(
name="private", cidr_mask=24,
reserved=False, subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT)
],
enable_dns_hostnames=True,
enable_dns_support=True
)
CfnOutput(
self,
id="VPCId",
value=self.vpc.vpc_id,
description="VPC ID",
export_name=f"{self.region}:{self.account}:{self.stack_name}:vpc-id"
)
我们可以看到,一旦这个堆栈部署完毕,它将通过控制台以及AWS CloudFormation输出选项卡来输出VPC的详细信息。
淘宝网
MWAA的环境堆栈更有趣一些,我将对其进行分解。堆栈的第一部分是配置MWAA将使用的Amazon S3桶。
Shell
from aws_cdk import (
aws_iam as iam,
aws_ec2 as ec2,
aws_s3 as s3,
aws_s3_deployment as s3deploy,
aws_mwaa as mwaa,
aws_kms as kms,
Stack,
CfnOutput,
Tags
)
from constructs import Construct
class MwaaCdkStackEnv(Stack):
def __init__(self, scope: Construct, id: str, vpc, mwaa_props, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
key_suffix = 'Key'
# Create MWAA S3 Bucket and upload local dags
s3_tags = {
'env': f"{mwaa_props['mwaa_env']}",
'service': 'MWAA Apache AirFlow'
}
dags_bucket = s3.Bucket(
self,
"mwaa-dags",
bucket_name=f"{mwaa_props['dagss3location'].lower()}",
versioned=True,
block_public_access=s3.BlockPublicAccess.BLOCK_ALL
)
for tag in s3_tags:
Tags.of(dags_bucket).add(tag, s3_tags[tag])
s3deploy.BucketDeployment(self, "DeployDAG",
sources=[s3deploy.Source.asset("./dags")],
destination_bucket=dags_bucket,
destination_key_prefix="dags",
prune=False,
retain_on_delete=False
)
dags_bucket_arn = dags_bucket.bucket_arn
然而,这也是它在本地dags文件夹中发现的所有文件(在这个特定的例子中,以及GitHub repo中的内容,这将是两个DAG,sample-cdk-day-od.py和sample-cdk-day.py),并将这些文件作为部署过程的一部分上传。如果你愿意,你可以根据自己的要求进行调整,如果你不需要这样做,甚至可以根据需要注释它/删除它。
接下来,我们有创建MWAA执行策略和相关角色的代码,这些角色将被MWAA工作节点使用。这是从MWAA文档中摘录的,但你可以根据自己的环境需要来调整。如果你要与其他AWS服务集成,你可能需要这样做 - 这已经设置了默认的无访问权限,所以你需要做的任何事情都需要添加。
Shell
mwaa_policy_document = iam.PolicyDocument(
statements=[
iam.PolicyStatement(
actions=["airflow:PublishMetrics"],
effect=iam.Effect.ALLOW,
resources=[f"arn:aws:airflow:{self.region}:{self.account}:environment/{mwaa_props['mwaa_env']}"],
),
iam.PolicyStatement(
actions=[
"s3:ListAllMyBuckets"
],
effect=iam.Effect.DENY,
resources=[
f"{dags_bucket_arn}/*",
f"{dags_bucket_arn}"
],
),
iam.PolicyStatement(
actions=[
"s3:*"
],
effect=iam.Effect.ALLOW,
resources=[
f"{dags_bucket_arn}/*",
f"{dags_bucket_arn}"
],
),
iam.PolicyStatement(
actions=[
"logs:CreateLogStream",
"logs:CreateLogGroup",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:GetLogRecord",
"logs:GetLogGroupFields",
"logs:GetQueryResults",
"logs:DescribeLogGroups"
],
effect=iam.Effect.ALLOW,
resources=[f"arn:aws:logs:{self.region}:{self.account}:log-group:airflow-{mwaa_props['mwaa_env']}-*"],
),
iam.PolicyStatement(
actions=[
"logs:DescribeLogGroups"
],
effect=iam.Effect.ALLOW,
resources=["*"],
),
iam.PolicyStatement(
actions=[
"sqs:ChangeMessageVisibility",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes",
"sqs:GetQueueUrl",
"sqs:ReceiveMessage",
"sqs:SendMessage"
],
effect=iam.Effect.ALLOW,
resources=[f"arn:aws:sqs:{self.region}:*:airflow-celery-*"],
),
iam.PolicyStatement(
actions=[
"ecs:RunTask",
"ecs:DescribeTasks",
"ecs:RegisterTaskDefinition",
"ecs:DescribeTaskDefinition",
"ecs:ListTasks"
],
effect=iam.Effect.ALLOW,
resources=[
"*"
],
),
iam.PolicyStatement(
actions=[
"iam:PassRole"
],
effect=iam.Effect.ALLOW,
resources=[ "*" ],
conditions= { "StringLike": { "iam:PassedToService": "ecs-tasks.amazonaws.com" } },
),
iam.PolicyStatement(
actions=[
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:PutKeyPolicy"
],
effect=iam.Effect.ALLOW,
resources=["*"],
conditions={
"StringEquals": {
"kms:ViaService": [
f"sqs.{self.region}.amazonaws.com",
f"s3.{self.region}.amazonaws.com",
]
}
},
),
]
)
mwaa_service_role = iam.Role(
self,
"mwaa-service-role",
assumed_by=iam.CompositePrincipal(
iam.ServicePrincipal("airflow.amazonaws.com"),
iam.ServicePrincipal("airflow-env.amazonaws.com"),
iam.ServicePrincipal("ecs-tasks.amazonaws.com"),
),
inline_policies={"CDKmwaaPolicyDocument": mwaa_policy_document},
path="/service-role/"
)
下一部分是配置MWAA所需的安全组和子网。
Shell
security_group = ec2.SecurityGroup(
self,
id = "mwaa-sg",
vpc = vpc,
security_group_name = "mwaa-sg"
)
security_group_id = security_group.security_group_id
security_group.connections.allow_internally(ec2.Port.all_traffic(),"MWAA")
subnets = [subnet.subnet_id for subnet in vpc.private_subnets]
network_configuration = mwaa.CfnEnvironment.NetworkConfigurationProperty(
security_group_ids=[security_group_id],
subnet_ids=subnets,
)
从MWAA的角度来看,最后一个部分是最有趣的,那就是设置然后配置环境。我已经注释了一些环境设置,所以可以根据自己的需要自由调整。
我们要做的第一件事是为MWAA日志创建一个配置。在这个特定的配置中,我启用了所有INFO级别的日志,所以请随意启用/禁用或根据你的需要改变日志级别。
Shell
logging_configuration = mwaa.CfnEnvironment.LoggingConfigurationProperty(
dag_processing_logs=mwaa.CfnEnvironment.ModuleLoggingConfigurationProperty(
enabled=True,
log_level="INFO"
),
task_logs=mwaa.CfnEnvironment.ModuleLoggingConfigurationProperty(
enabled=True,
log_level="INFO"
),
worker_logs=mwaa.CfnEnvironment.ModuleLoggingConfigurationProperty(
enabled=True,
log_level="INFO"
),
scheduler_logs=mwaa.CfnEnvironment.ModuleLoggingConfigurationProperty(
enabled=True,
log_level="INFO"
),
webserver_logs=mwaa.CfnEnvironment.ModuleLoggingConfigurationProperty(
enabled=True,
log_level="INFO"
)
)
接下来我们定义一些MWAA Apache Airflow配置参数。如果你使用自定义属性,那么这就是你要添加它们的地方。另外,如果你想为你的MWAA环境使用TAG,你可以进行相应的调整。
Shell
options = {
'core.load_default_connections': False,
'core.load_examples': False,
'webserver.dag_default_view': 'tree',
'webserver.dag_orientation': 'TB'
}
tags = {
'env': f"{mwaa_props['mwaa_env']}",
'service': 'MWAA Apache AirFlow'
}
接下来,我们需要创建一些额外的IAM策略和权限,以及AWS KMS加密密钥,以保持所有内容的加密。如果你在配置MWAA环境时决定不配置KMS加密,那么这部分是可选的,但我在这里包括了信息。
Shell
kms_mwaa_policy_document = iam.PolicyDocument(
statements=[
iam.PolicyStatement(
actions=[
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Decrypt*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:ScheduleKeyDeletion",
"kms:GenerateDataKey*",
"kms:CancelKeyDeletion"
],
principals=[
iam.AccountRootPrincipal(),
# Optional:
# iam.ArnPrincipal(f"arn:aws:sts::{self.account}:assumed-role/AWSReservedSSO_rest_of_SSO_account"),
],
resources=["*"]),
iam.PolicyStatement(
actions=[
"kms:Decrypt*",
"kms:Describe*",
"kms:GenerateDataKey*",
"kms:Encrypt*",
"kms:ReEncrypt*",
"kms:PutKeyPolicy"
],
effect=iam.Effect.ALLOW,
resources=["*"],
principals=[iam.ServicePrincipal("logs.amazonaws.com", region=f"{self.region}")],
conditions={"ArnLike": {"kms:EncryptionContext:aws:logs:arn": f"arn:aws:logs:{self.region}:{self.account}:*"}},
),
]
)
key = kms.Key(
self,
f"{mwaa_props['mwaa_env']}{key_suffix}",
enable_key_rotation=True,
policy=kms_mwaa_policy_document
)
key.add_alias(f"alias/{mwaa_props['mwaa_env']}{key_suffix}")
现在我们来实际创建环境,使用我们在上面创建或设置的东西。以下是MWAA中Apache Airflow核心选项的所有典型配置选项。你可以改变它们以适应你自己的环境,或如上所述对它们进行参数化。
Shell
managed_airflow = mwaa.CfnEnvironment(
scope=self,
id='airflow-test-environment',
name=f"{mwaa_props['mwaa_env']}",
airflow_configuration_options={'core.default_timezone': 'utc'},
airflow_version='2.0.2',
dag_s3_path="dags",
environment_class='mw1.small',
execution_role_arn=mwaa_service_role.role_arn,
kms_key=key.key_arn,
logging_configuration=logging_configuration,
max_workers=5,
network_configuration=network_configuration,
#plugins_s3_object_version=None,
#plugins_s3_path=None,
#requirements_s3_object_version=None,
#requirements_s3_path=None,
source_bucket_arn=dags_bucket_arn,
webserver_access_mode='PUBLIC_ONLY',
#weekly_maintenance_window_start=None
)
managed_airflow.add_override('Properties.AirflowConfigurationOptions', options)
managed_airflow.add_override('Properties.Tags', tags)
CfnOutput(
self,
id="MWAASecurityGroup",
value=security_group_id,
description="Security Group name used by MWAA"
)
这个堆栈还输出MWAA安全组,但你也可以输出其他信息。
部署你的CDK应用程序
现在我们已经审查了该应用程序,并修改了它,使其包含你的详细信息(你的AWS帐户/独特的S3桶/等等),你现在可以运行该应用程序并部署CDK栈。要做到这一点,我们使用 "cdk deploy" 命令。
首先,从目录中,确保一切工作正常。要做到这一点,我们可以使用 "cdk ls" 命令。如果工作正常,它应该返回以下信息(这些信息是这个CDK应用程序使用的堆栈中分配的ID)。
Shell
cdk ls
>MWAA-Backend
>MWAA-Environment
我们现在可以部署它们,可以全部部署,也可以一次部署一个。这个CDK应用程序需要先部署MWAA-Backend应用程序,因为它包含了将在MWAA-Environment堆栈中使用的VPC网络,所以我们可以通过部署它。
Shell
cdk deploy MWAA-Backend
如果工作正常,它应该类似于下面的情况。
纯文本
✨ Synthesis time: 7.09s
mwaa-hybrid-backend: deploying...
[0%] start: Publishing 2695cb7a9f601cf94a4151c65c9069787d9ec312084346f2f4359e3f55ff2310:704533066374-eu-central-1
[100%] success: Published 2695cb7a9f601cf94a4151c65c9069787d9ec312084346f2f4359e3f55ff2310:704533066374-eu-central-1
mwaa-hybrid-backend: creating CloudFormation changeset...
✅ mwaa-hybrid-backend
✨ Deployment time: 172.13s
Outputs:
mwaa-hybrid-backend.ExportsOutputRefMWAAHybridApacheAirflowVPC677B092EF6F2F587 = vpc-0bbdeee3652ef21ff
mwaa-hybrid-backend.ExportsOutputRefMWAAHybridApacheAirflowVPCprivateSubnet1Subnet2A6995DF7F8D3134 = subnet-01e48db64381efc7f
mwaa-hybrid-backend.ExportsOutputRefMWAAHybridApacheAirflowVPCprivateSubnet2SubnetA28659530C36370A = subnet-0321530b8154f9bd2
mwaa-hybrid-backend.VPCId = vpc-0bbdeee3652ef21ff
Stack ARN:
arn:aws:cloudformation:eu-central-1:704533066374:stack/mwaa-hybrid-backend/b05897d0-f087-11ec-b5f3-02db3f47a5ca
✨ Total time: 179.22s
然后,你可以通过AWS控制台检查CloudFormation栈来跟踪/查看已经部署的内容。
我们现在可以部署MWAA环境了,我们可以简单地通过键入来完成。
Shell
cdk deploy MWAA-Environment
这一次,它将弹出一些与安全有关的信息的细节,在这种情况下,就是我前面提到的IAM策略和安全组。回答 "Y "以部署这些变化。这将启动部署,你可以通过进入CloudFormation控制台跟踪。
这将需要大约20-25分钟,所以是一个很好的时间,拿起一杯茶,也许可以阅读一些我的其他博客文章:-)如果成功了,你会看到以下输出(同样,你的细节会改变,但它应该与此相似)。
纯文本
Including dependency stacks: mwaa-hybrid-backend
[Warning at /mwaa-hybrid-environment/mwaa-sg] Ignoring Egress rule since 'allowAllOutbound' is set to true; To add customize rules, set allowAllOutbound=false on the SecurityGroup
✨ Synthesis time: 12.37s
mwaa-hybrid-backend
mwaa-hybrid-backend: deploying...
[0%] start: Publishing 2695cb7a9f601cf94a4151c65c9069787d9ec312084346f2f4359e3f55ff2310:704533066374-eu-central-1
[100%] success: Published 2695cb7a9f601cf94a4151c65c9069787d9ec312084346f2f4359e3f55ff2310:704533066374-eu-central-1
✅ mwaa-hybrid-backend (no changes)
✨ Deployment time: 1.97s
Outputs:
mwaa-hybrid-backend.ExportsOutputRefMWAAHybridApacheAirflowVPC677B092EF6F2F587 = vpc-0bbdeee3652ef21ff
mwaa-hybrid-backend.ExportsOutputRefMWAAHybridApacheAirflowVPCprivateSubnet1Subnet2A6995DF7F8D3134 = subnet-01e48db64381efc7f
mwaa-hybrid-backend.ExportsOutputRefMWAAHybridApacheAirflowVPCprivateSubnet2SubnetA28659530C36370A = subnet-0321530b8154f9bd2
mwaa-hybrid-backend.VPCId = vpc-0bbdeee3652ef21ff
Stack ARN:
arn:aws:cloudformation:eu-central-1:704533066374:stack/mwaa-hybrid-backend/b05897d0-f087-11ec-b5f3-02db3f47a5ca
✨ Total time: 14.35s
mwaa-hybrid-environment
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 │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${Custom::CDKBucketDeploymen │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
│ │ t8693BB64968944B69AAFB0CC9EB │ │ │ │ │
│ │ 8756C/ServiceRole.Arn} │ │ │ │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${mwaa-dags.Arn} │ Deny │ s3:ListAllMyBuckets │ AWS:${mwaa-service-role} │ │
│ │ ${mwaa-dags.Arn}/* │ │ │ │ │
│ + │ ${mwaa-dags.Arn} │ Allow │ s3:* │ AWS:${mwaa-service-role} │ │
│ │ ${mwaa-dags.Arn}/* │ │ │ │ │
│ + │ ${mwaa-dags.Arn} │ Allow │ s3:Abort* │ AWS:${Custom::CDKBucketDeplo │ │
│ │ ${mwaa-dags.Arn}/* │ │ s3:DeleteObject* │ yment8693BB64968944B69AAFB0C │ │
│ │ │ │ s3:GetBucket* │ C9EB8756C/ServiceRole} │ │
│ │ │ │ s3:GetObject* │ │ │
│ │ │ │ s3:List* │ │ │
│ │ │ │ s3:PutObject │ │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${mwaa-hybrid-demoKey.Arn} │ Allow │ kms:CancelKeyDeletion │ AWS:arn:${AWS::Partition}:ia │ │
│ │ │ │ kms:Create* │ m::704533066374:root │ │
│ │ │ │ kms:Decrypt* │ │ │
│ │ │ │ kms:Delete* │ │ │
│ │ │ │ kms:Describe* │ │ │
│ │ │ │ kms:Disable* │ │ │
│ │ │ │ kms:Enable* │ │ │
│ │ │ │ kms:GenerateDataKey* │ │ │
│ │ │ │ kms:Get* │ │ │
│ │ │ │ kms:List* │ │ │
│ │ │ │ kms:Put* │ │ │
│ │ │ │ kms:Revoke* │ │ │
│ │ │ │ kms:ScheduleKeyDeletion │ │ │
│ │ │ │ kms:Update* │ │ │
│ + │ ${mwaa-hybrid-demoKey.Arn} │ Allow │ kms:Decrypt* │ Service:logs.eu-central-1.am │ "ArnLike": { │
│ │ │ │ kms:Describe* │ azonaws.com │ "kms:EncryptionContext:aws:lo │
│ │ │ │ kms:Encrypt* │ │ gs:arn": "arn:aws:logs:eu-centr │
│ │ │ │ kms:GenerateDataKey* │ │ al-1:704533066374:*" │
│ │ │ │ kms:PutKeyPolicy │ │ } │
│ │ │ │ kms:ReEncrypt* │ │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${mwaa-service-role.Arn} │ Allow │ sts:AssumeRole │ Service:airflow-env.amazonaw │ │
│ │ │ │ │ s.com │ │
│ │ │ │ │ Service:airflow.amazonaws.co │ │
│ │ │ │ │ m │ │
│ │ │ │ │ Service:ecs-tasks.amazonaws. │ │
│ │ │ │ │ com │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ * │ Allow │ logs:DescribeLogGroups │ AWS:${mwaa-service-role} │ │
│ + │ * │ Allow │ ecs:DescribeTaskDefinition │ AWS:${mwaa-service-role} │ │
│ │ │ │ ecs:DescribeTasks │ │ │
│ │ │ │ ecs:ListTasks │ │ │
│ │ │ │ ecs:RegisterTaskDefinition │ │ │
│ │ │ │ ecs:RunTask │ │ │
│ + │ * │ Allow │ iam:PassRole │ AWS:${mwaa-service-role} │ "StringLike": { │
│ │ │ │ │ │ "iam:PassedToService": "ecs-t │
│ │ │ │ │ │ asks.amazonaws.com" │
│ │ │ │ │ │ } │
│ + │ * │ Allow │ kms:Decrypt │ AWS:${mwaa-service-role} │ "StringEquals": { │
│ │ │ │ kms:DescribeKey │ │ "kms:ViaService": [ │
│ │ │ │ kms:Encrypt │ │ "sqs.eu-central-1.amazonaws │
│ │ │ │ kms:GenerateDataKey* │ │ .com", │
│ │ │ │ kms:PutKeyPolicy │ │ "s3.eu-central-1.amazonaws. │
│ │ │ │ │ │ com" │
│ │ │ │ │ │ ] │
│ │ │ │ │ │ } │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ arn:${AWS::Partition}:s3:::c │ Allow │ s3:GetBucket* │ AWS:${Custom::CDKBucketDeplo │ │
│ │ dk-hnb659fds-assets-70453306 │ │ s3:GetObject* │ yment8693BB64968944B69AAFB0C │ │
│ │ 6374-eu-central-1 │ │ s3:List* │ C9EB8756C/ServiceRole} │ │
│ │ arn:${AWS::Partition}:s3:::c │ │ │ │ │
│ │ dk-hnb659fds-assets-70453306 │ │ │ │ │
│ │ 6374-eu-central-1/* │ │ │ │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ arn:aws:airflow:eu-central-1 │ Allow │ airflow:PublishMetrics │ AWS:${mwaa-service-role} │ │
│ │ :704533066374:environment/mw │ │ │ │ │
│ │ aa-hybrid-demo │ │ │ │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ arn:aws:logs:eu-central-1:70 │ Allow │ logs:CreateLogGroup │ AWS:${mwaa-service-role} │ │
│ │ 4533066374:log-group:airflow │ │ logs:CreateLogStream │ │ │
│ │ -mwaa-hybrid-demo-* │ │ logs:DescribeLogGroups │ │ │
│ │ │ │ logs:GetLogEvents │ │ │
│ │ │ │ logs:GetLogGroupFields │ │ │
│ │ │ │ logs:GetLogRecord │ │ │
│ │ │ │ logs:GetQueryResults │ │ │
│ │ │ │ logs:PutLogEvents │ │ │
├───┼──────────────────────────────┼────────┼──────────────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ arn:aws:sqs:eu-central-1:*:a │ Allow │ sqs:ChangeMessageVisibility │ AWS:${mwaa-service-role} │ │
│ │ irflow-celery-* │ │ sqs:DeleteMessage │ │ │
│ │ │ │ sqs:GetQueueAttributes │ │ │
│ │ │ │ sqs:GetQueueUrl │ │ │
│ │ │ │ sqs:ReceiveMessage │ │ │
│ │ │ │ sqs:SendMessage │ │ │
└───┴──────────────────────────────┴────────┴──────────────────────────────┴──────────────────────────────┴─────────────────────────────────┘
IAM Policy Changes
┌───┬───────────────────────────────────────────────────────────────────┬───────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼───────────────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────┤
│ + │ ${Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/Ser │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasic │
│ │ viceRole} │ ExecutionRole │
└───┴───────────────────────────────────────────────────────────────────┴───────────────────────────────────────────────────────────────────┘
Security Group Changes
┌───┬────────────────────┬─────┬────────────┬────────────────────┐
│ │ Group │ Dir │ Protocol │ Peer │
├───┼────────────────────┼─────┼────────────┼────────────────────┤
│ + │ ${mwaa-sg.GroupId} │ In │ Everything │ ${mwaa-sg.GroupId} │
│ + │ ${mwaa-sg.GroupId} │ Out │ Everything │ Everyone (IPv4) │
└───┴────────────────────┴─────┴────────────┴────────────────────┘
(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
mwaa-hybrid-environment: deploying...
[0%] start: Publishing e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68:704533066374-eu-central-1
[0%] start: Publishing 983c442a2fe823a8b4ebb18d241a5150ae15103dacbf3f038c7c6343e565aa4c:704533066374-eu-central-1
[0%] start: Publishing 91ab667f7c88c3b87cf958b7ef4158ef85fb9ba8bd198e5e0e901bb7f904d560:704533066374-eu-central-1
[0%] start: Publishing f2a926ee3d8ca4bd02b0cf073eb2bbb682e94c021925bf971a9730045ef4fb02:704533066374-eu-central-1
[25%] success: Published 983c442a2fe823a8b4ebb18d241a5150ae15103dacbf3f038c7c6343e565aa4c:704533066374-eu-central-1
[50%] success: Published 91ab667f7c88c3b87cf958b7ef4158ef85fb9ba8bd198e5e0e901bb7f904d560:704533066374-eu-central-1
[75%] success: Published f2a926ee3d8ca4bd02b0cf073eb2bbb682e94c021925bf971a9730045ef4fb02:704533066374-eu-central-1
[100%] success: Published e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68:704533066374-eu-central-1
mwaa-hybrid-environment: creating CloudFormation changeset...
✅ mwaa-hybrid-environment
✨ Deployment time: 1412.35s
Outputs:
mwaa-hybrid-environment.MWAASecurityGroup = sg-0ea83e01caded2bb3
Stack ARN:
arn:aws:cloudformation:eu-central-1:704533066374:stack/mwaa-hybrid-environment/450337a0-f088-11ec-a169-06ba63bfdfb2
✨ Total time: 1424.72s
测试环境
如果我们看一下Amazon S3桶,我们可以看到我们已经创建了MWAA桶和dags文件夹,以及上传了我们的本地DAG。
如果我们去MWAA控制台,我们可以看到我们的环境
我们现在可以抓取这个环境的URL,可以从控制台获取,也可以使用AWS CLI。只需替换MWAA环境和AWS区域的名称,然后它应该给你一个可以在浏览器中使用的URL(尽管你必须在它后面加上/home)。
注意,我使用的是jq,如果你的环境中没有这个,你可以不运行这个命令,但只需要在输出中找到 "WebserverUrl "的条目。
Shell
aws mwaa get-environment --name {name of the environment created} --region={region} | jq -r '.Environment | .WebserverUrl'
我们可以看到,我们有两个在本地文件夹中的样本DAGS,现在可以在MWAA环境中使用。
拆除/清理我们的MWAA环境
为了删除我们所部署的一切,我们所要做的就是。
Shell
cdk destroy MWAA-Environment
清理MWAA的环境需要20-30分钟。然而,它不会做的一件事是删除我们设置的亚马逊S3桶,所以你将需要通过控制台手动删除它(或使用AWS CLI - 这将是我的方法)。一旦你删除了S3桶,现在清理后端堆栈
Shell
cdk destroy MWAA-Backend
这样清理起来应该会快得多。一旦完成,你应该就可以了。