Getting new secrets

Before I waste hours going down the wrong paths trying to get my Laravel app to read from Secrets Manager, I wanted to make sure I was in the right neighborhood.

  1. I created a secret called LaravelSecrets with a key/value pair called APP_KEY=‘xxxxxxxxxxx’. I accepted all the default settings save for these fields.

  2. I created this Resource stanza in my template.yml file:

  LaravelSecret:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      Parameters:
        KmsKeyModule: !GetAtt 'LaravelSecret.Outputs.StackName'
        Description: !Sub '${AWS::StackName}: Laravel secret'
      TemplateURL: './node_modules/@cfn-modules/secret/module.yml'
  1. and added this to the AppService stanza:
        AppEnvironment5Key: 'APP_KEY'
        AppEnvironment5SecretModule: !GetAtt 'LaravelSecret.Outputs.StackName'

That look right to everyone? Have I missed anything?

LaravelSecret : Your KmsKeyModule looks wrong. Copy from the ruby-rails example like this KmsKeyModule: !GetAtt 'Key.Outputs.StackName'

AppService : Only the first 3 AppEnvironment* blocks support the SecretModule. Make sure to rearrange your config accordingly. see https://github.com/cfn-modules/fargate-service#usage

Thanks for that last piece of advice; I never would have guessed AWS would have done something like that.

This also means I need to find another mechanism since I have six or so “secrets” to deal with. One approach I’m going to try is storing the env files on S3 and copy them over the appropriate one when I spin up the container. How you do that while in CloudFormation I have no idea.

Why do you have 6 secrets? :slight_smile:

Unless I’m sorely mistaken, all instances of my containers need to access the same information: APP_KEY; database host, name, user, password; AWS access key and secret key. None of this can be stored in the git repo or the codebase.

I think I need to use cfn-init to copy over the appropriate environment file when spinning up. Then I’ll have three template files: one for remote, staging, and production environments whose only difference is which cfn_init they use (maybe?).

If y’all know of a better way to handle this I would love to hear it.

@faberfedor The only secrets you need is APP_KEY and the db password (please look at the ruby-rails example!).

database host, name, user are not secrets. You can pass them in plain text as we do in all our examples:

AppService:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      Parameters:
        # [...]
        AppEnvironment2Key: 'dbhost' # increase the index accordingly
        AppEnvironment2Value: '1.2.3.4'

DO NOT use static AWS access keys! Each Fargate container runs in the context of an IAM role. You can pass policies to that role via the ManagedPolicyArns parameter.

E.g., with a custom policy (recommended):

AppPolicy:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Action: 's3:PutObject'
          Resource: 'arn:aws:s3:::bucket_name/*'
AppService:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      Parameters:
        # [...]
        ManagedPolicyArns: !Ref AppPolicy

Or using AWS managed policies (not recommended):

AppService:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
      Parameters:
        # [...]
        ManagedPolicyArns: 'arn:aws:iam::aws:policy/AmazonS3FullAccess,arn:aws:iam::aws:policy/AmazonS3FullAccess,arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess'

Why am I only seeing this now?

So the above AppPolicy will allow my AppService to put objects in S3, yes?

I’m guessing I want to setup a policy to have AppService get the appropriate environment file from S3 and somehow copy it into my container. :-?

yes, s3:PutObject := upload.

But if I understand you use case, you need s3:GetObject := download instead, right?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.