Pulumi は、インフラストラクチャをコードとして管理するための強力なツールであり、さまざまな言語に柔軟に対応できるため、開発者の間で人気の選択肢となっています。 Pulumi の TypeScript 構文は、出力と入力を処理するクリーンで便利な方法を提供しますが、これらの機能を Python に変換するのは困難な場合があります。この記事では、TypeScript での pulumi.interpolate の使用の微妙な違いと、Python で同様の機能を実現する方法について説明します。
Pulumi の TypeScript 構文には、出力を連結するためのクリーンなアプローチがあります。これは、Python では使用できないタグ付きテンプレート リテラルを利用します。 Pulumi のリファレンス ドキュメントによると、 interpolate は concat に似ていますが、タグ付きのテンプレート式として使用するように設計されています。例:
// 'server' and 'loadBalancer' are both resources that expose [Output] properties. let val: Output<string> = pulumi.interpolate `http://${server.hostname}:${loadBalancer.port}`
concat と同様に、${} の間の「プレースホルダー」は任意の入力にすることができます。つまり、Promise、Output、または単純な JavaScript 値にすることができます。
Pulumi の作業のほとんどを TypeScript で行ってきたので、新しいリソースに入力を渡す必要があるときは常に、pulumi.interpolate タグ付きテンプレート リテラルを頻繁に使用しました。あまり深く考えず、pulumi.concatやapplyと深く比較せずに使いまくってしまいました。しかし、Python で Pulumi を使い始めて pulumi.interpolate に手を伸ばしたときに、それが欠落していることに気付きました。
これにより、出力と入力の意味、および変換方法についてさらに深く理解することができました。
pulumi.interpolate`http://${server.hostname}:${loadBalancer.port}`
宛先:
pulumi.concat('http://', server.hostname, ':', loadBalancer.port)
出力は、設定される可能性がある、または将来解決されて設定されるリソースからの値です。出力はその出力元のリソースに関連付けられているため、入力として pulumi.interpolate または pulumi.concat に渡すときにエッジを作成し、後で別のリソースの作成に使用できます。ノード (リソース) とそのエッジ (出力 -> 入力) によって作成されるリソース間の依存関係グラフにより、Pulumi は正しい順序でリソースを作成でき、グラフ内の次のリソースで必要なときに出力が確実に設定されるようになります。
入力は、生の値、Promise、または出力にすることができます。リソースへの入力が出力である場合、出力が最初に作成されたリソースへの参照があります。入力が出力になる可能性があるという事実により、その依存関係を追跡できます。
その型定義は次のとおりです:
type Input<T> = T | Promise<T> | OutputInstance<T>;
テンプレート リテラルのリテラル文字列部分を変更せずに、値 (${} の間の「プレースホルダー」) のみを大文字にする方法の例を次に示します。
function uppercaseValues(strings, ...values) { const result = []; strings.forEach((string, i) => { result.push(string); if (i < values.length) { result.push(values[i].toString().toUpperCase()); } }); return result.join(''); } const name = "Chris"; const hobby = "TypeScript"; console.log(uppercaseValues`Hello, my name is ${name} and I love ${hobby}.`); // Output: "Hello, my name is CHRIS and I love TYPESCRIPT."
正確なソース コードを知らなくても、上記の例から拡張することで、自分で pulumi.interpolate を実装する方法を想像できます。次のようになります:
function interpolate(strings, ...values) { const result = []; strings.forEach((string, i) => { result.push(string); if (i < values.length) { result.push(values[i]); } }); return pulumi.concat(...result); }
私たちが行ったのは、最後の join 呼び出しを pulumi.concat への呼び出しに置き換えるだけです。これが実装である場合、実際の実装ではプレースホルダーのみを操作するのではなく、生の文字列を出力型からアンラップする必要があるかどうかのチェックを実行します。
TypeScript での関数定義は次のとおりです:
function interpolate(literals: TemplateStringsArray, ...placeholders: Input<any>[]): Output<string>;
これは concat に非常に似ています:
function concat(...params: Input<any>[]): Output<string>
実際には出力値に沿って転送し、親出力でラップしているだけであることに気づいたとき、電球の瞬間が来ます。
interpolate を concat に移植するときに、いくつかの愚かな間違いを犯す可能性があります。例を使って説明しましょう。
TypeScript では、次のようにします:
function get_image_name(imageRegistry: Repository, name: string, version: Input<string>) { return pulumi.interpolate`${image_registry.repository_id}/${name}:${version}` }
Python に移植すると、次のようになります:
def get_image_tag(image_registry: Repository, name: str, version: Input[str]): return pulumi.Output.concat( image_registry.repository_id, f"/{name}:{version}" )
ただし、interpolate はすべてのプレースホルダーを個別に反復して依存関係を作成し、出力を解決していました。私たちの Python コードでは、バージョン引数との関係が微妙に失われています。出力を手動で分割し、pulumi.Output.concat.
への個別の引数として表示する必要があります。修正されたコードは次のようになります:
def get_image_tag(image_registry: Repository, name: str, version: Input[str]): return pulumi.Output.concat( image_registry.repository_id, f"/{name}:", version )
これで、バージョンが依存関係グラフに正しく含まれるようになり、エラーがなくなりました!
pulumi.interpolate を TypeScript から Python に変換するには、Pulumi での出力と入力がどのように機能するかをより深く理解する必要があります。 Python はタグ付きテンプレート リテラルをサポートしていませんが、pulumi.concat を効果的に使用すると、同様の機能を実現できます。依存関係を手動で管理し、すべての出力値が適切に処理されるようにすることで、Python の Pulumi コードが TypeScript と同じくらい堅牢かつ効率的であることを保証できます。
以上がPython の Pulumi: 補間の翻訳の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。