CDK -如何在userdata中使用Opensearch Domain MasterUserPassword



在Opensearch L2结构中,如果您添加细粒度访问控制,将在秘密管理器中为您创建一个秘密(可通过masterUserPassword访问)。

我想在CloudformationInit中使用这个生成的密码,但不确定如何。

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
}}
}}
""",
)
)
)

由于SecretValue没有secretId属性,我不确定如何确定masterUserPassword的秘密ID/Arn。

是否有更好的方法在我的logstash配置中获得生成的凭据?

username值很简单,因为您显式地将其设置为osadmin。要获取password引用,在域的master_user_password属性上调用to_string方法,这是一个SecretValue:

domain.master_user_password.to_string()

在合成模板中,这被转换为对秘密密码的CloudFormation动态引用。模板不知道实际的密码。它将在部署时在云端解决。

SecretsValue.secrets_manager静态方法也综合了相同的动态引用。然而,你不能使用它。该方法需要秘密ID,如果Domain构造为您生成秘密,则不会公开该ID。

我最终向CloudFormationInit添加命令以从秘密管理器中提取操作系统凭据,并进行了查找和替换

from aws_cdk import aws_ec2 as ec2
from aws_cdk import aws_opensearchservice as opensearch
from aws_cdk import aws_s3 as s3
from aws_cdk import aws_secretsmanager as secretsmanager
from aws_cdk import Stack
from constructs import Construct

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",
),
)
# Get the domain secret
domain_secret: secretsmanager.Secret = domain.node.find_child("MasterUser")
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 => "REPLACE_WITH_USERNAME"
password => "REPLACE_WITH_PASSWORD"
ecs_compatibility => disabled
}}
}}
""",
),
ec2.InitPackage.yum("jq"),  # install jq
ec2.InitCommand.shell_command(
shell_command=(
f"aws configure set region {self.region} && "
# save secret value to variable
f"OS_SECRET=$(aws secretsmanager get-secret-value --secret-id {domain_secret.secret_arn} "
"--query SecretString) && "
# Pull values from json string
"OS_USER=$(echo $OS_SECRET | jq -r '. | fromjson | .username') && "
"OS_PASS=$(echo $OS_SECRET | jq -r '. | fromjson | .password') && "
# Find and replace
"sed -i "s/REPLACE_WITH_USERNAME/$OS_USER/g" /home/ec2-user/logstash-8.4.0/config/my_conf.conf && "
"sed -i "s/REPLACE_WITH_PASSWORD/$OS_PASS/g" /home/ec2-user/logstash-8.4.0/config/my_conf.conf"
),
),
)
)
# Don't forget to grant the instance read access to the secret
domain_secret.grant_read(instance.role)

最新更新