Share
Embed
Transcript
32 slides
-
#hashtag まっとうな選択肢 • AWS CDKを諦め、Terraformを使う • CDK for Terraform cdk-terrainを使う
• AWS CDKを使えるように説得する • 最初AWS CDKで書いてTerraformに変換する -
#hashtag お話しすること • AWS CDKからTerraformへ変換するフローについて ◦ 変換ツール ◦ 足掻きの記録 •
社内交渉 • なぜTerraformなのか お話ししないこと -
#hashtag ざっくりやること 1. AWS CDKで実装 2. cdk synth 3. 変換
4. terraform validate 5. terraform plan / apply -
#hashtag 簡単な構成を AWS CDKで作成する 1. NodejsFunctionによる暗黙的なリソース生成 2. アプリケーションコードのデプロイ 3. API
Gateway → SQS Integration -
#hashtag export class Cf2TfCdkStack extends cdk.Stack { constructor(scope: Construct, id:
string, props?: cdk.StackProps) { super(scope, id, props) const queue = new sqs.Queue(this, 'RequestQueue') const processor = new lambdaNodejs.NodejsFunction(this, 'Processor', { entry: path.join(__dirname, '../lambda/processor.ts'), handler: 'handler', runtime: lambda.Runtime.NODEJS_24_X, n environment: { QUEUE_URL: queue.queueUrl, }, }) processor.addEventSource( new lambdaEventSources.SqsEventSource(queue), ) const api = new apigateway.RestApi(this, 'Api') const integrationRole = new iam.Role(this, 'ApiGwSqsRole', assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com') }) 簡単な構成を AWS CDKで作成する queue.grantSendMessages(integrationRole) const sqsIntegration = new apigateway.AwsIntegration({ service: 'sqs', path: `${cdk.Aws.ACCOUNT_ID}/${queue.queueName}`, integrationHttpMethod: 'POST', options: { credentialsRole: integrationRole, ==== 略 ==== }, }) const messages = api.root.addResource('messages') messages.addMethod('POST', sqsIntegration, { methodResponses: [ { statusCode: '200' }, ], }) } } -
#hashtag cf2tf Cloudformation 2 Terraform cf2tf is a CLI tool
that attempts to convert Cloudformation to Terraform. We say attempt because it's not really possible to make the conversion with 100% accuracy (currently) because of several reasons mostly around converting a Map value in Cloudformation to the correct value in HCL. https://github.com/DontShaveTheYak/cf2tf CloudFormationをTerraformに変換しようとする CLIツールです。 -
#hashtag template.jsonをcf2tfで変換 $ cf2tf cdk-stack/cdk.out/CdkStack.template.json -o terraform-stack $ ls terraform-stack
data.tf locals.tf output.tf resource.tf variable.tf -o, --output PATH 各リソースを特定のファイル(variables.tf、outputs.tfなど)に保存する -
#hashtag terraform validate $ terraform validate │ Warning: Deprecated attribute
│ Error: Incorrect attribute value type │ Error: Missing required argument -
#hashtag ① ざっくり直す • object → JSON文字列 ◦ jsonencode({ ...
}) で修正 • 不要なCDKメタデータ用リソースは削除 -
#hashtag ① ざっくり直す resource "aws_iam_role" "api_gw_sqs_role767_c34_b1" { - assume_role_policy =
{ + assume_role_policy = jsonencode({ Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "apigateway.amazonaws.com" } } ] Version = "2012-10-17" - } + }) } -
#hashtag ① ざっくり直す - resource "aws_s3_bucket_metadata_configuration" "cdk_metadata" { - count
= local.CDKMetadataAvailable ? 1 : 0 - // CF Property(Analytics) = "v2:deflate64:H...." - } -
#hashtag resource "aws_api_gateway_method" "apimessages_post934_e6315" { authorization = "NONE" - //
CF Property(Integration) = { - // Credentials = aws_iam_role.api_gw_sqs_role767_c34_b1.arn - // IntegrationHttpMethod = "POST" - // IntegrationResponses = [ - // { - // ResponseTemplates = { - // application/json = "{"message": "Message sent to queue"}" - // } - // StatusCode = "200" - // } - // ] http_method = "POST" + resource_id = aws_api_gateway_resource.apimessages76_cde0_c9.id + rest_api_id = aws_api_gateway_rest_api.api_f70053_cd.id } ② リソースモデルを直す -
#hashtag ② リソースモデルを直す + resource "aws_api_gateway_method_response" "apimessages_post_method_response" { + rest_api_id
= aws_api_gateway_rest_api.api_f70053_cd.id + resource_id = aws_api_gateway_resource.apimessages76_cde0_c9.id + http_method = aws_api_gateway_method.apimessages_post934_e6315.http_method + status_code = "200" + } -
#hashtag ③ ビルドまでやらせる • esbuildでLambdaをローカルビルド • archive_fileでZIP化 resource "null_resource" "lambda_build"
{ triggers = { source_hash = filebase64sha256("${path.module}/lambda/processor.ts") } provisioner "local-exec" { command = "npm ci && npm run build" working_dir = "${path.module}/lambda" } } data "archive_file" "processor_lambda" { type = "zip" source_file = "${path.module}/lambda/dist/index.js" output_path = "${path.module}/lambda/dist/processor.zip" depends_on = [null_resource.lambda_build] } -
#hashtag terraform plan / apply $ terraform apply Apply complete!
Resources: 3 added, 0 changed, 0 destroyed. -
#hashtag ざっくりやること 1. AWS CDKで実装 2. cdk synth 3. cf2tfで変換
4. terraform validate 5. terraform plan / apply 型の不一致: 5箇所 リソースタイプの誤り: 2箇所 属性名の誤り: 3箇所 未変換 / 依存関係 / 設計: 3箇所 合計13箇所 ゴリゴリTerraform書いてるくね? -
#hashtag まとめ • Terraform標準でも、初期実装にAWS CDKを使うことは可能 ◦ 標準的な開発方法としては選ばない ▪ 今回の例では変換後に合計13箇所の手修正が必要だった ▪
継続的に変更するアジャイルな開発フローには向かない • cf2tfはいいツール ◦ 60点の土台を作ってくれる ◦ Terraformを学ぶ教材として使える ◦ 多くの問題はcf2tf側を改善することで解決できる(と思っている) ▪ JSON文字列が必要な属性をjsonencodeする ▪ .arnと.idの誤変換を修正する • 改善可能な部分はcf2tfへ還元していく -
#hashtag まっとうな選択肢 • AWS CDKを諦め、Terraformを使う • CDK for Terraform cdk-terrainを使う
• AWS CDKを使えるように説得する • 最初AWS CDKで書いてTerraformに変換する -
#hashtag • AWS CDKを諦め、Terraformを使う • CDK for Terraform cdk-terrainを使う •
AWS CDKを使えるように説得する • 最初AWS CDKで書いてTerraformに変換する まっとうな選択肢