Skip to content

Commit 799e0da

Browse files
authored
AWS Airflow (#271)
1 parent bff9969 commit 799e0da

File tree

4 files changed

+305
-0
lines changed

4 files changed

+305
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Effect": "Allow",
6+
"Action": "airflow:PublishMetrics",
7+
"Resource": "arn:aws:airflow:${aws_region}:${aws_account_id}:environment/${airflow_name}"
8+
},
9+
{
10+
"Effect": "Deny",
11+
"Action": "s3:ListAllMyBuckets",
12+
"Resource": [
13+
"arn:aws:s3:::${s3_bucket_name}",
14+
"arn:aws:s3:::${s3_bucket_name}/*"
15+
]
16+
},
17+
{
18+
"Effect": "Allow",
19+
"Action": [
20+
"s3:GetObject*",
21+
"s3:GetBucket*",
22+
"s3:List*"
23+
],
24+
"Resource": [
25+
"arn:aws:s3:::${s3_bucket_name}",
26+
"arn:aws:s3:::${s3_bucket_name}/*"
27+
]
28+
},
29+
{
30+
"Effect": "Allow",
31+
"Action": [
32+
"logs:CreateLogStream",
33+
"logs:CreateLogGroup",
34+
"logs:PutLogEvents",
35+
"logs:GetLogEvents",
36+
"logs:GetLogRecord",
37+
"logs:GetLogGroupFields",
38+
"logs:GetQueryResults"
39+
],
40+
"Resource": [
41+
"arn:aws:logs:${aws_region}:${aws_account_id}:log-group:airflow-${airflow_name}-*"
42+
]
43+
},
44+
{
45+
"Effect": "Allow",
46+
"Action": [
47+
"logs:DescribeLogGroups"
48+
],
49+
"Resource": [
50+
"*"
51+
]
52+
},
53+
{
54+
"Effect": "Allow",
55+
"Action": [
56+
"s3:GetAccountPublicAccessBlock"
57+
],
58+
"Resource": [
59+
"*"
60+
]
61+
},
62+
{
63+
"Effect": "Allow",
64+
"Action": "cloudwatch:PutMetricData",
65+
"Resource": "*"
66+
},
67+
{
68+
"Effect": "Allow",
69+
"Action": [
70+
"sqs:ChangeMessageVisibility",
71+
"sqs:DeleteMessage",
72+
"sqs:GetQueueAttributes",
73+
"sqs:GetQueueUrl",
74+
"sqs:ReceiveMessage",
75+
"sqs:SendMessage"
76+
],
77+
"Resource": "arn:aws:sqs:${aws_region}:*:airflow-celery-*"
78+
},
79+
{
80+
"Effect": "Allow",
81+
"Action": [
82+
"kms:Decrypt",
83+
"kms:DescribeKey",
84+
"kms:GenerateDataKey*",
85+
"kms:Encrypt"
86+
],
87+
"Resource": "arn:aws:kms:${aws_region}:${aws_account_id}:key/*",
88+
"Condition": {
89+
"StringLike": {
90+
"kms:ViaService": [
91+
"sqs.${aws_region}.amazonaws.com",
92+
"s3.${aws_region}.amazonaws.com"
93+
]
94+
}
95+
}
96+
}
97+
]
98+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
resource "aws_mwaa_environment" "this" {
2+
name = var.airflow_name
3+
airflow_version = var.airflow_version
4+
environment_class = var.environment_class
5+
max_workers = var.max_workers
6+
min_workers = var.min_workers
7+
source_bucket_arn = var.source_bucket_arn
8+
dag_s3_path = var.dag_s3_path
9+
execution_role_arn = module.iam_assumable_role_admin.iam_role_arn
10+
11+
logging_configuration {
12+
dag_processing_logs {
13+
enabled = true
14+
log_level = var.dag_processing_log_level
15+
}
16+
17+
scheduler_logs {
18+
enabled = true
19+
log_level = var.scheduler_log_level
20+
}
21+
22+
task_logs {
23+
enabled = true
24+
log_level = var.task_log_level
25+
}
26+
27+
webserver_logs {
28+
enabled = true
29+
log_level = var.webserver_log_level
30+
}
31+
32+
worker_logs {
33+
enabled = true
34+
log_level = var.worker_log_level
35+
}
36+
}
37+
38+
network_configuration {
39+
security_group_ids = [aws_security_group.this.id]
40+
subnet_ids = var.subnet_ids
41+
}
42+
43+
tags = var.tags
44+
}
45+
46+
data "aws_caller_identity" "current" {}
47+
48+
module "iam_assumable_role_admin" {
49+
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
50+
version = "4.14.0"
51+
52+
create_role = true
53+
role_name = "airflow-${var.airflow_name}"
54+
role_description = "Airflow role"
55+
trusted_role_services = ["airflow.amazonaws.com","airflow-env.amazonaws.com"]
56+
custom_role_policy_arns = [aws_iam_policy.policy.arn]
57+
role_requires_mfa = false
58+
tags = var.tags
59+
}
60+
61+
resource "aws_iam_policy" "policy" {
62+
name_prefix = "cluster-autoscaler-${var.airflow_name}"
63+
description = "Airflow policy"
64+
policy = templatefile("default_iam_policy.json", {
65+
aws_region = var.aws_region
66+
aws_account_id = data.aws_caller_identity.current.account_id
67+
airflow_name = var.airflow_name
68+
s3_bucket_name = var.source_bucket_name
69+
})
70+
71+
tags = var.tags
72+
}
73+
74+
resource "aws_security_group" "this" {
75+
name = var.airflow_name
76+
description = "Airflow security group"
77+
vpc_id = var.vpc_id
78+
79+
ingress {
80+
description = "TLS from VPC"
81+
from_port = 0
82+
to_port = 0
83+
protocol = "-1"
84+
cidr_blocks = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
85+
}
86+
87+
egress {
88+
from_port = 0
89+
to_port = 0
90+
protocol = "-1"
91+
cidr_blocks = ["0.0.0.0/0"]
92+
ipv6_cidr_blocks = ["::/0"]
93+
}
94+
95+
tags = var.tags
96+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
output "arn" {
2+
value = aws_mwaa_environment.this.arn
3+
}
4+
5+
output "webserver_url" {
6+
value = aws_mwaa_environment.this.webserver_url
7+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
variable "airflow_name" {
2+
type = string
3+
default = "airflow"
4+
description = "Airflow name"
5+
}
6+
7+
variable "aws_region" {
8+
type = string
9+
default = "us-east-1"
10+
description = "The AWS region"
11+
}
12+
13+
variable "vpc_id" {
14+
type = string
15+
default = ""
16+
description = "The vpc ID"
17+
}
18+
19+
variable "subnet_ids" {
20+
type = list(string)
21+
default = []
22+
description = "(Required) The private subnet IDs in which the environment should be created. MWAA requires two subnets."
23+
}
24+
25+
variable "airflow_version" {
26+
type = string
27+
default = null
28+
description = "(Optional) Airflow version of your environment, will be set by default to the latest version that MWAA supports."
29+
}
30+
31+
32+
variable "environment_class" {
33+
type = string
34+
default = "mw1.small"
35+
description = "(Optional) Environment class for the cluster. Possible options are mw1.small, mw1.medium, mw1.large. Will be set by default to mw1.small. Please check the AWS Pricing for more information about the environment classes."
36+
}
37+
38+
variable "max_workers" {
39+
type = number
40+
default = 10
41+
description = "(Optional) The maximum number of workers that can be automatically scaled up. Value need to be between 1 and 25. Will be 10 by default."
42+
}
43+
44+
variable "min_workers" {
45+
type = number
46+
default = 1
47+
description = "(Optional) The minimum number of workers that you want to run in your environment. Will be 1 by default."
48+
}
49+
50+
51+
52+
variable "source_bucket_arn" {
53+
type = string
54+
default = "s3://foo"
55+
description = "The Dag's S3 bucket arn: arn:aws:s3:::bucketname"
56+
}
57+
58+
variable "source_bucket_name" {
59+
type = string
60+
default = "foo"
61+
description = "The Dag's S3 bucket name"
62+
}
63+
64+
variable "dag_s3_path" {
65+
type = string
66+
default = "dags/"
67+
description = "The dag's S3 path"
68+
}
69+
70+
variable "tags" {
71+
type = any
72+
default = {}
73+
description = "A set of tags to place on the items"
74+
}
75+
76+
variable "dag_processing_log_level" {
77+
type = string
78+
default = "INFO"
79+
description = "The log level: INFO | WARNING | ERROR | CRITICAL"
80+
}
81+
82+
variable "scheduler_log_level" {
83+
type = string
84+
default = "INFO"
85+
description = "The log level: INFO | WARNING | ERROR | CRITICAL"
86+
}
87+
88+
variable "task_log_level" {
89+
type = string
90+
default = "INFO"
91+
description = "The log level: INFO | WARNING | ERROR | CRITICAL"
92+
}
93+
94+
variable "webserver_log_level" {
95+
type = string
96+
default = "INFO"
97+
description = "The log level: INFO | WARNING | ERROR | CRITICAL"
98+
}
99+
100+
variable "worker_log_level" {
101+
type = string
102+
default = "INFO"
103+
description = "The log level: INFO | WARNING | ERROR | CRITICAL"
104+
}

0 commit comments

Comments
 (0)