更新日付:2022年6月29日
皆さま、はじめまして、DXビジネス推進本部 運用開発グループの木村です。TerraformでAWS Data Pipelineを作成するのが思っていたより大変だったので、作成する際に自分が感じたことと最終的にどうやって作成したのか共有したいと思います。
Terraformとは
TerraformはHashicorp社により開発されたIaCツールの一種です。Terraformではインフラの構成をコードで宣言することで、手動で操作することなくインフラ構成を自動で管理できます。インフラの構築、更新、破棄、いずれもTerraformではコードにより宣言して実行することができます。
TerraformでData Pipelineを作成しようと思った経緯
TerraformでData Pipelineを作成しようと思ったのは、DynamoDBのデータをS3にアーカイブするためです。DynamoDBからS3へのデータエクスポート方法を色々調べた結果、今回はData Pipelineで実施するのが良さそうという結論になり、DynamoDBやS3といったAWSリソースは全てTerraformで管理していたため、Data PipelineもTerraformで管理することになりました。
TerraformでData Pipelineを作成
Data Pipelineのtfファイル作成
まず、Data Pipeline関係のTerraformリソースは以下の2種類になります。
aws_datapipeline_pipelineでは特に設定する値は無いので、aws_datapipeline_pipeline_definitionの方でDynamoDBのデータをS3にエクスポートするための設定を記載していくのですが…公式のサンプル見てもkeyとstring_valueの項目に色々と設定値が書かれているだけで、全然使い方が分かりませんでした。
公式のサンプル
resource "aws_datapipeline_pipeline" "default" {
name = "tf-pipeline-default"
}
resource "aws_datapipeline_pipeline_definition" "example" {
pipeline_id = aws_datapipeline_pipeline.default.id
pipeline_object {
id = "Default"
name = "Default"
field {
key = "workerGroup"
string_value = "workerGroup"
}
}
pipeline_object {
id = "Schedule"
name = "Schedule"
field {
key = "startDateTime"
string_value = "2012-12-12T00:00:00"
}
field {
key = "type"
string_value = "Schedule"
}
field {
key = "period"
string_value = "1 hour"
}
field {
key = "endDateTime"
string_value = "2012-12-21T18:00:00"
}
}
pipeline_object {
id = "SayHello"
name = "SayHello"
field {
key = "type"
string_value = "ShellCommandActivity"
}
field {
key = "command"
string_value = "echo hello"
}
field {
key = "parent"
string_value = "Default"
}
field {
key = "schedule"
string_value = "Schedule"
}
}
}
Data Pipelineの公式ドキュメントにPipeline Object Referenceがあり、ここに記載されている値をkeyとかに設定すれば良いらしいのですが…はっきり言ってかなり面倒ですし、かなり大変だと思います。というわけで自分はひとまずAWSマネジメントコンソールで作成してから、terraform importコマンド等で後からTerraform管理対象にすることにしました。
【参考】DynamoDB、S3、IAMのtfファイル
参考までにDynamoDB、S3、Data Pipeline用のIAMのtfファイルも記載しておきます。
dynamodb.tf
resource "aws_dynamodb_table" "dynamodb_sample" {
name = "dynamodb_sample"
billing_mode = "PAY_PER_REQUEST"
hash_key = "PartitionKey"
range_key = "RowKey"
attribute {
name = "PartitionKey"
type = "S"
}
attribute {
name = "RowKey"
type = "S"
}
}
s3.tf
resource "aws_s3_bucket" "sample_bucket" {
bucket = "sample_bucket"
force_destroy = true
}
resource "aws_s3_bucket_public_access_block" "sample_bucket_public_access_block" {
bucket = aws_s3_bucket.sample_bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
iam.tf
resource "aws_iam_role" "sample_datapipeline_role" {
name = "sample_datapipeline_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"datapipeline.amazonaws.com",
"elasticmapreduce.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "sample_datapipeline_policy_attachment" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSDataPipelineRole"
role = aws_iam_role.sample_datapipeline_role.name
}
resource "aws_iam_role" "sample_datapipeline_role_for_ec2" {
name = "sample_datapipeline_role_for_ec2"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "sample_datapipeline_role_for_ec2_policy_attachment" {
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforDataPipelineRole"
role = aws_iam_role.sample_datapipeline_role_for_ec2.name
}
resource "aws_iam_instance_profile" "sample_datapipeline_instance_profile" {
name = aws_iam_role.sample_datapipeline_role_for_ec2.name
role = aws_iam_role.sample_datapipeline_role_for_ec2.name
}
諦めてAWSマネジメントコンソールから作成する
AWSマネジメントコンソールでData Pipelineの作成
マネジメントコンソールでCreate new pipelineをクリックし、Export DynamoDB table to S3 Data Pipeline テンプレートを選択すれば、後は表示通りにDynamoDBテーブル名やS3バケット名、Schedule、使用するIAMロール等を入力するだけで簡単に作成できます。
入力が完了したらActivateをクリックしてData Pipelineを作成し、S3にエクスポートされることが確認できたら完了です。
マネジメントコンソールで作成したData PipelineをTerraform管理にする
マネジメントコンソールで作成したData Pipelineをtfstateに反映するためにterraform importを実行し、次にterraform state showを実行して表示されたコードをtfファイルに記載していきます。まずはterraform importを実行するために、Data Pipeline用のtfファイルを作成します。
datapipeline.tf
resource "aws_datapipeline_pipeline" "sample_datapipeline" {
}
resource "aws_datapipeline_pipeline_definition" "sample_datapipeline_definition" {
}
terraform import
以下のterraform importコマンドを実行してtfstateに反映します。
$ terraform import aws_datapipeline_pipeline.sample_datapipeline <Pipeline ID>
$ terraform import aws_datapipeline_pipeline_definition.sample_datapipeline_definition <Pipeline ID>
terraform state show
以下のterraform state showコマンドを実行することで、マネジメントコンソールで作成したData Pipelineがtfファイルだとどんなコードになるか確認できます。後は表示されたコードをdatapipeline.tfにコピーすれば、マネジメントコンソールで作成したData PipelineをTerraformの管理下におくことができます。
$ terraform state show aws_datapipeline_pipeline.sample_datapipeline
# aws_datapipeline_pipeline.sample_datapipeline:
resource "aws_datapipeline_pipeline" "sample_datapipeline" {
id = "df-03319771VET6AXN3W3N7"
name = "iot_datapipeline_dynamodb_export_to_s3_dev"
tags = {}
tags_all = {}
}
$ terraform state show aws_datapipeline_pipeline_definition.sample_datapipeline_definition
# aws_datapipeline_pipeline_definition.sample_datapipeline_definition:
resource "aws_datapipeline_pipeline_definition" "sample_datapipeline_definition" {
...(200行くらいあるので省略)
}
DynamoDBやS3名をTerraformリソースに修正
terraform state showコマンドで表示されるコードはDynamoDBテーブル名やS3バケット名などがベタ書きされているので、aws_dynamodb_table.dynamodb_sample.nameやaws_s3_bucket.sample_bucket.idなどに置換しておくと良いです。
まとめ
Data PipelineをTerraformで作成するのはかなり大変だと思うので、どうしてもTerraformで管理したいときには、一度マネジメントコンソールで作成してからterraformのコマンドを利用してtfファイルを作成してしまうのがおすすめです。一度コードにしてしまえば、出力先のS3を変更したり、Scheduleを変更する程度であればtfファイルを編集し、Terraformで簡単に更新することができます。