Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Terraform標準の組織で AWS CDKをどう使うか

Terraform標準の組織で AWS CDKをどう使うか

More Decks by mu7889yoon / Yuta Nakamura

Other Decks in Programming

Transcript

  1. #hashtag まっとうな選択肢 • AWS CDKを諦め、Terraformを使う • CDK for Terraform cdk-terrainを使う

    • AWS CDKを使えるように説得する • 最初AWS CDKで書いてTerraformに変換する
  2. #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' }, ], }) } }
  3. #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ツールです。
  4. #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など)に保存する
  5. #hashtag terraform validate $ terraform validate │ Warning: Deprecated attribute

    │ Error: Incorrect attribute value type │ Error: Missing required argument
  6. #hashtag ① ざっくり直す • object → JSON文字列 ◦ jsonencode({ ...

    }) で修正 • 不要なCDKメタデータ用リソースは削除
  7. #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" - } + }) }
  8. #hashtag ① ざっくり直す - resource "aws_s3_bucket_metadata_configuration" "cdk_metadata" { - count

    = local.CDKMetadataAvailable ? 1 : 0 - // CF Property(Analytics) = "v2:deflate64:H...." - }
  9. #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 } ② リソースモデルを直す
  10. #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" + }
  11. #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] }
  12. #hashtag terraform plan / apply $ terraform apply Apply complete!

    Resources: 3 added, 0 changed, 0 destroyed.
  13. #hashtag ざっくりやること 1. AWS CDKで実装 2. cdk synth 3. cf2tfで変換

    4. terraform validate 5. terraform plan / apply 型の不一致: 5箇所 リソースタイプの誤り: 2箇所 属性名の誤り: 3箇所 未変換 / 依存関係 / 設計: 3箇所 合計13箇所 ゴリゴリTerraform書いてるくね?
  14. #hashtag まとめ • Terraform標準でも、初期実装にAWS CDKを使うことは可能 ◦ 標準的な開発方法としては選ばない ▪ 今回の例では変換後に合計13箇所の手修正が必要だった ▪

    継続的に変更するアジャイルな開発フローには向かない • cf2tfはいいツール ◦ 60点の土台を作ってくれる ◦ Terraformを学ぶ教材として使える ◦ 多くの問題はcf2tf側を改善することで解決できる(と思っている) ▪ JSON文字列が必要な属性をjsonencodeする ▪ .arnと.idの誤変換を修正する • 改善可能な部分はcf2tfへ還元していく
  15. #hashtag まっとうな選択肢 • AWS CDKを諦め、Terraformを使う • CDK for Terraform cdk-terrainを使う

    • AWS CDKを使えるように説得する • 最初AWS CDKで書いてTerraformに変換する
  16. #hashtag • AWS CDKを諦め、Terraformを使う • CDK for Terraform cdk-terrainを使う •

    AWS CDKを使えるように説得する • 最初AWS CDKで書いてTerraformに変換する まっとうな選択肢