You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CDK技术问询:如何在CloudFormationInit中使用OpenSearch主用户密码

在CDK中获取OpenSearch自动生成的Secrets Manager凭据用于Logstash配置

问题描述

在使用AWS CDK创建OpenSearch L2构造并开启细粒度访问控制后,Secrets Manager会自动生成包含主用户凭据的密钥。需要在后续的CloudFormationInit中,将该凭据填入Logstash配置文件,但无法确定自动生成的Secret ID/ARN,且SecretValue没有直接的secretId属性。相关代码示例如下:

from aws_cdk import aws_ec2 as ec2
from aws_cdk import aws_iam as iam
from aws_cdk import aws_opensearchservice as opensearch
from aws_cdk import aws_s3 as s3


class OpensearchStack(Stack):
    def __init__(
        self,
        scope: Construct,
        construct_id: str,
        **kwargs,
    ) -> None:
        super().__init__(scope, construct_id, **kwargs)

        vpc = ec2.Vpc(self, "generatorVpc", max_azs=2)
        bucket = s3.Bucket(self, "My Bucket")
        domain = opensearch.Domain(self,"OpensearchDomain",
            version=opensearch.EngineVersion.OPENSEARCH_1_3,
            vpc=vpc,
            fine_grained_access_control=opensearch.AdvancedSecurityOptions(
                master_user_name="osadmin",
            ),
        )
        instance = ec2.Instance(self, "Instance",
            vpc=vpc,
            instance_type=ec2.InstanceType.of(
                instance_class=ec2.InstanceClass.M5,
                instance_size=ec2.InstanceSize.LARGE,
            ),
            machine_image=ec2.MachineImage.latest_amazon_linux(
                generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
            ),
            init=ec2.CloudFormationInit.from_elements(
                ec2.InitFile.from_string(
                            file_name="/home/ec2-user/logstash-8.4.0/config/my_conf.conf",
                            owner="ec2-user",
                            mode="00755",
                            content=f"""input {{
    s3 {{
        bucket => "{bucket.bucket_name}"
        region => "{self.region}"
    }}
}}
output {{
    opensearch {{
        hosts => ["{domain.domain_endpoint}:443"]
        user => "{domain.master_user_password.secrets_manager("What secret id do I put here?", json_field="username")}"
        password => "{domain.master_user_password.secrets_manager("What secret id do I put here?", json_field="password")}"
        ecs_compatibility => disabled
    }}
}}
""",
                )
            )
        )

解决方案

1. 获取自动生成的Secret ARN

当你通过AdvancedSecurityOptions指定master_user_name但不提供master_user_password时,CDK会自动创建Secrets Manager密钥,该密钥的ARN可通过OpenSearch Domain的master_user_secret.secret_arn属性直接获取。

2. 为EC2实例添加读取Secret的权限

EC2实例需要拥有读取该Secret的IAM权限,否则初始化过程中无法解析凭据:

# 给EC2实例的角色添加读取Secret的权限
instance.role.add_to_policy(iam.PolicyStatement(
    actions=["secretsmanager:GetSecretValue"],
    resources=[domain.master_user_secret.secret_arn]
))

3. 在Logstash配置中动态引用Secret值

使用CDK的SecretValue.secrets_manager()方法生成CloudFormation动态引用字符串,直接嵌入到配置文件中:

# 生成用户名和密码的动态引用
os_user = str(opensearch.SecretValue.secrets_manager(
    domain.master_user_secret.secret_arn,
    json_field="username"
))
os_password = str(opensearch.SecretValue.secrets_manager(
    domain.master_user_secret.secret_arn,
    json_field="password"
))

# 初始化文件内容
init_file = ec2.InitFile.from_string(
    file_name="/home/ec2-user/logstash-8.4.0/config/my_conf.conf",
    owner="ec2-user",
    mode="00755",
    content=f"""input {{
    s3 {{
        bucket => "{bucket.bucket_name}"
        region => "{self.region}"
    }}
}}
output {{
    opensearch {{
        hosts => ["{domain.domain_endpoint}:443"]
        user => "{os_user}"
        password => "{os_password}"
        ecs_compatibility => disabled
    }}
}}
"""
)

# 实例初始化
instance = ec2.Instance(self, "Instance",
    vpc=vpc,
    instance_type=ec2.InstanceType.of(
        instance_class=ec2.InstanceClass.M5,
        instance_size=ec2.InstanceSize.LARGE,
    ),
    machine_image=ec2.MachineImage.latest_amazon_linux(
        generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
    ),
    init=ec2.CloudFormationInit.from_elements(init_file)
)

原理说明

SecretValue.secrets_manager()会生成类似{{resolve:secretsmanager:arn:aws:secretsmanager:region:account-id:secret:secret-name:SecretString:username}}的字符串,CloudFormation在创建EC2实例时会自动解析该引用,将实际的用户名和密码填入配置文件中。

内容的提问来源于stack exchange,提问作者maafk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:00:48