Ribtoks
Ribtoks

Reputation: 6922

How to create IAM user with access key and secret key using Serverless framework?

I'd like to use Serverless framework to create an IAM user for programmatic access with certain Policies attached to it and export it's Access Key ID and Secret Key as environment variables for lambda. How to achieve that?

(something like here is done with terraform)

Upvotes: 2

Views: 1384

Answers (2)

Ribtoks
Ribtoks

Reputation: 6922

Here's how to add a user with roles and permissions set up. Setting up roles and permissions is important since usually you don't create a user with Access/Secret key in a vacuum, the user needs to have some accesses.

Notes:

  • All IAM resources need to have a region in the name since redeployment a resource with the same name will cause an "unrecoverable error" (accordingly to AWS IAM documentation)
  • To reference the Access Key you just specify resource name, but to reference the Secret Key you need to get property SecretAccessKey.
  • Sample permissions in the policy give access to an SQS queue, but it can be anything

File serverless-with-my-user.yml:

resources:
  Resources:
    # Naming an IAM resource can cause an unrecoverable error if you reuse the same template in multiple Regions
    MyUser:
      Type: AWS::IAM::User
      Properties:
        UserName: "my-${self:provider.stage}-${self:provider.region}-User"
        Policies:
        - PolicyName: 
            Fn::Join:
              - ''
              - - "myUser"
                - '-'
                - ${self:provider.stage}
                - '-'
                - ${self:provider.region}
                - '-MyPolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action:
                - "sqs:GetQueueAttributes"
                - "sqs:GetQueueUrl"
              Resource: { 'Fn::ImportValue': '${self:provider.stage}-MyQueueArn' }
    MyUserKey:
      Type: AWS::IAM::AccessKey
      Properties: 
        UserName:
          Ref: MyUser

  Outputs:
    MyUserAccessKeyID:
      Description: The Access Key of the MyUser
      Value:
        Ref: MyUserKey
      Export:
        Name: ${self:provider.stage}-MyUserAccessKeyID
    MyUserAccessSecretKey:
      Description: The ARN of the secret key
      Value:
        Fn::GetAtt:
          - MyUserKey
          - SecretAccessKey
      Export:
        Name: ${self:provider.stage}-MyUserAccessSecretKey

And here's how to access this user's access key and secret key in other parts of serverless resources (e.g. lambda):

File serverless-with-my-service.yml

environment:
  MYUSER_AWS_ACCESS_KEY_ID:
    Fn::ImportValue: '${self:provider.stage}-MyUserAccessKeyID'
  MYUSER_AWS_SECRET_ACCESS_KEY:
    Fn::ImportValue: '${self:provider.stage}-MyUserAccessSecretKey'

If user, key and service are in a single file, there's no need to use output variables and you can reference the values directly.

Upvotes: 2

pgrzesik
pgrzesik

Reputation: 2427

you can do that by writing raw CloudFormation in resources section: https://www.serverless.com/framework/docs/providers/aws/guide/resources.

However, one note - it is not recommended to pass AWS Access Keys directly to Lambda - it's better to use IAM Role that is assigned to Lambda to grant it proper permissions.

EDIT: Example on how to access it

provider:
  name: aws
  environment:
    ENVVAR:
      'Fn::GetAtt':
        - MyKey
        - SecretAccessKey

resources:
  Resources:
    MyKey:
      Type: AWS::IAM::AccessKey
      Properties: 
        Serial: 0
        Status: Active
        UserName: username

I want to reiterate once again that it's a really bad idea to do something like the above - you should rely on temporary credentials from assumed role instead.

Upvotes: 0

Related Questions