@ckcalbut
Nothing here yet.
Nothing here yet.
No blogs yet.
Hi Stefan, May I ask why you decided to use a SNS Topic with a Lambda subscribed to it? Con: It seems like an extra step because you could just invoked the lambda at the end of the UserData script instead of writing to the SNS Topic at the end of the UserData script, which causes the lambda to be invoked. Pro: It does seem cleaner to separate the concerns of the lambda running successfully and the UserData script installing Typesense successfully. Was this your thinking or am I missing something?
Stefan Olaru Took a me a while (converted to cdk and changed/added some things), but here is what I did to generate the bootstrap api key and startup the typesense instance: Have AWS Secretsmanager generate the bootstrap api key without it ever touching my laptop: typesense_bootstrap_api_key = secretsmanager.Secret(self, "TypesenseBootstrapAPIKeySecret" , secret_name= "TypesenseBootstrapAPIKey" , generate_secret_string=secretsmanager.SecretStringGenerator( exclude_uppercase= True , exclude_punctuation= True , password_length= 64 , ), ) Get the Bootstrap API Key from SecretsManager upon execution of the UserData: sudo yum install jq # get the api key for bootstrapping typesense secretsmanager_resp=$(aws secretsmanager get-secret-value \ --secret-id {typesense_bootstrap_api_key.secret_name}) ApiKey=$( echo $secretsmanager_resp | jq -r .SecretString) The Typesense EC2 Instance IAM Role needs additional permissions to get this secret from SecretsManager. I created a SecretsManagerReadOnlyPolicy and attached it to the role: secrets_manager_read_only_policy = iam.ManagedPolicy(self, "SecretsManagerReadOnlyPolicy" , managed_policy_name= "SecretsManagerReadOnly" , statements=[iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=[ "secretsmanager:GetResourcePolicy" , "secretsmanager:GetSecretValue" , "secretsmanager:DescribeSecret" , "secretsmanager:ListSecretVersionIds" ], resources=[ "*" ] )] ) I do end up using a lambda function to generate api keys. It gets the bootstrap or admin key (depending on what keyname you pass in the payload) from secretsmanager, reaches out to typesense to generate a new key with whatever name and permissions were passed in the payload, and then stores that new key in secretsmanager. Hopefully this can be run to generate the basic keys I'd want (admin, readwrite, readonly, idk what else) upon CDK deploy, but I don't have a great way to ensure it runs after the typesense server actually starts up for the first time without doing something very hacky. By the way, my UserData script needed this addition to get the EC2_INSTANCE_ID: # get instance-id TOKEN=$(curl -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 600" "http://instance-data/latest/api/token" ) EC2_INSTANCE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN " -s http://instance-data/latest/meta-data/instance-id) This is all built into a greater cdk project I have going, but I will pull this out and put it in a public repo when I have time.
I appreciate your post. Thank you. I have one concern: It seems like half of the UserData bash script should be part of the CFN code instead. Specifically these steps should all be in CFN so that CloudFormation can track the resources, no?: # get instance-id # associate the Elastic IP address to the instance # attach volume # wait for volume to be properly attached # format the volume if doesn't have file system # create mount root folder # mount the volume to folder