Class: MistAws::Iam

Inherits:
Object
  • Object
show all
Defined in:
lib/mist_aws/iam.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ MistAws::Iam

Initializes all you need to access aws resources in a region You can create multiple instances to allow access to multiple regions in one program/recipe

Parameters:

  • opts (Hash) (defaults to: {})

    the key/value pairs for the initializer

Options Hash (opts):

  • :profile_name (String) — default: 'default' or ENV['AWS_PROFILE']

    profile name to use to get creds from ~/.aws/credentials.

  • :region (String) — default: us-east-1 or ENV['AWS_REGION']

    AWS Region to use

  • :logger (Logger) — default: STDERR

    A logger instance to use for logging



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/mist_aws/iam.rb', line 32

def initialize(opts={})
  # Ruby 1.9 backwards compatability
  opts = {profile_name: nil, region: nil, logger: ::Logger.new(STDERR)}.merge(opts)
  opts.each do |key, value|
    instance_variable_set "@#{key}", value
  end

  # Set by rspec tests that are testing methods called by initialize
  return if ENV['RSPEC_IGNORE_INITIALIZE']

  @region ||= ENV['AWS_REGION'] ? ENV['AWS_REGION'] : 'us-east-1'

  # Note get_creds also resolves and sets @profile_name as well as
  # fetching the appropriate credentials based on the value of
  # profile_name and various Environment Variables
  @credentials = get_creds(profile_name)

  @iam_client = ::Aws::IAM::Client.new(credentials: @credentials, region: @region)
  @iam = ::Aws::IAM::Resource.new(client: @iam_client)
end

Instance Attribute Details

#credentialsObject (readonly)

Returns the value of attribute credentials.



15
16
17
# File 'lib/mist_aws/iam.rb', line 15

def credentials
  @credentials
end

#handleObject (readonly)

Returns the value of attribute handle.



18
19
20
# File 'lib/mist_aws/iam.rb', line 18

def handle
  @handle
end

#iamObject (readonly)

Returns the value of attribute iam.



20
21
22
# File 'lib/mist_aws/iam.rb', line 20

def iam
  @iam
end

#iam_clientObject (readonly)

Returns the value of attribute iam_client.



19
20
21
# File 'lib/mist_aws/iam.rb', line 19

def iam_client
  @iam_client
end

#loggerObject (readonly)

Returns the value of attribute logger.



17
18
19
# File 'lib/mist_aws/iam.rb', line 17

def logger
  @logger
end

#profile_nameObject (readonly)

These are read-only accessor and are initializeds by initialize method



14
15
16
# File 'lib/mist_aws/iam.rb', line 14

def profile_name
  @profile_name
end

#regionObject (readonly)

Returns the value of attribute region.



16
17
18
# File 'lib/mist_aws/iam.rb', line 16

def region
  @region
end

Instance Method Details

#create_iam_role(role_name, policy_name, policy_document, instance_profile_name = nil) ⇒ Object

Create an IAM role to be assigned to an ec2 instance Returns the Role object

Parameters:

  • role_name (String)

    Name of the role to create

  • policy_name (String)


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/mist_aws/iam.rb', line 152

def create_iam_role(role_name, policy_name, policy_document, instance_profile_name=nil)
  result = role_exists? role_name
  if result
    logger.warn "MistAws::Iam#create_iam_role: Role: #{role_name.inspect} already exists; Doing nothing"
    return nil 
  end
  
  assume_role_policy = {
    "Version" => "2012-10-17",
    "Statement" => [
      {"Effect" => "Allow",
        "Principal" => {
          "Service" => [
            "ec2.amazonaws.com"
          ]
        },
        "Action" => ["sts:AssumeRole"]
      }
    ]
  }.to_json

  # Create the role
  role = iam.create_role(role_name: role_name, assume_role_policy_document: assume_role_policy)

  # Create a policy object associated to the role and stuff the policy document into it
  policy = ::Aws::IAM::RolePolicy.new(role_name: role_name, name: policy_name, client: iam_client)
  policy.put(policy_document: policy_document)

  # Create an instance_profile
  instance_profile = iam.create_instance_profile(instance_profile_name: instance_profile_name) unless instance_profile_exists?(instance_profile_name)
  instance_profile.add_role(role_name: role_name)
  role
end

#delete_iam_role(role_name, policy_name, instance_profile_name = nil) ⇒ Object

Delete role, policy and instance_profile if they exist



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/mist_aws/iam.rb', line 118

def delete_iam_role(role_name, policy_name, instance_profile_name=nil)
  unless role_exists? role_name
    logger.warn "MistAws::Iam#delete_iam_role: No role: #{role_name.inspect}; Doing nothing"
    return nil 
  end
  
  role = iam.role role_name

  # Removes the role from the instance_profiles
  # Deletes the instance_profile
  instance_profiles = role.instance_profiles
  instance_profiles.each do | instance_profile |
    instance_profile.remove_role role_name: role_name
    instance_profile.delete
  end

  # Delete the role_policies associated with the role
  role_policies = role.policies
  role_policies.each do | role_policy |
    role_policy.delete
  end

  # Delete the Role
  role.delete

  true
end

#get_creds(profile_name = nil) ⇒ ::Aws::SharedCredentials | ::Aws::Credentials

Returns the proper Aws credential object.

Parameters:

  • profile_name (String) (defaults to: nil)

    (nil) Name of profile

Returns:

  • (::Aws::SharedCredentials | ::Aws::Credentials)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/mist_aws/iam.rb', line 59

def get_creds(profile_name=nil)
  unless profile_name
    if ENV['AWS_PROFILE']
      @profile_name = ENV['AWS_PROFILE']
    else
      if ENV['AWS_ACCESS_KEY_ID'] && ENV['AWS_SECRET_ACCESS_KEY']
        return ::Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
      else
        @profile_name = 'default'
      end
    end
  else
    @profile_name = profile_name
  end

  begin
    ::Aws::SharedCredentials.new(profile_name: @profile_name)
  rescue StandardError => e
    @logger.error e.inspect
    raise e
  end
end

#instance_profile_exists?(instance_profile_name) ⇒ Boolean

Check if an instance profile exists

Returns:

  • (Boolean)


93
94
95
96
97
98
99
100
101
# File 'lib/mist_aws/iam.rb', line 93

def instance_profile_exists?(instance_profile_name)
  instance_profile = iam.instance_profile(instance_profile_name)
  case instance_profile.data_loaded?
  when true
    return instance_profile
  else
    return nil
  end
end

#role_exists?(role_name) ⇒ Boolean

Check if a role exists

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
# File 'lib/mist_aws/iam.rb', line 83

def role_exists?(role_name)
  begin
    iam_client.get_role role_name: role_name
  rescue ::Aws::IAM::Errors::NoSuchEntity
    return false
  end
  return true
end

#role_policy_exists?(role_name, policy_name) ⇒ Boolean

Check if there is a role_policy

Returns:

  • (Boolean)


104
105
106
107
108
109
110
111
112
113
# File 'lib/mist_aws/iam.rb', line 104

def role_policy_exists?(role_name, policy_name)
  begin
    iam_client.get_role_policy(role_name: role_name, policy_name: policy_name)
    exists = true
  rescue ::Aws::IAM::Errors::NoSuchEntityException
    logger.warn "No role_polcy: #{policy_name.inspect} for role: #{role_name.inspect}"
    exists = false
  end
  exists
end