func GetIAMInstanceProfile(name string) (IAMInstanceProfile, error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	params := &iam.GetInstanceProfileInput{
		InstanceProfileName: aws.String(name),
	}
	resp, err := svc.GetInstanceProfile(params)
	if err != nil {
		return IAMInstanceProfile{}, err
	}
	profile := new(IAMInstanceProfile)
	profile.Marshal(resp.InstanceProfile)
	return *profile, nil
}
GetIAMProfile returns a single IAM Profile that matches the provided name
package aws
import (
	"errors"
	"net/url"
	"os"
	"reflect"
	"regexp"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/murdinc/awsm/models"
	"github.com/murdinc/terminal"
	"github.com/olekukonko/tablewriter"
)
type IAMUsers []IAMUser
type IAMUser models.IAMUser
type IAMRoles []IAMRole
type IAMPolicies []IAMPolicy
type IAMRole models.IAMRole
type IAMPolicy models.IAMPolicy
type IAMPolicyDocument models.IAMPolicyDocument
type IAMInstanceProfiles []IAMInstanceProfile
type IAMInstanceProfile models.IAMInstanceProfile
func GetIAMUser(username string) (IAMUser, error) {
	user := new(IAMUser)
	params := &iam.GetUserInput{}
	if username != "" {
		params.SetUserName(username)
	}
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	resp, err := svc.GetUser(params)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok {
			return *user, errors.New(awsErr.Message())
		}
		return *user, err
	}
	user.Marshal(resp.User)
	return *user, nil
}
func GetIAMUsers(search string) (iamList *IAMUsers, err error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	result, err := svc.ListUsers(&iam.ListUsersInput{})  
	if err != nil {
		terminal.ShowErrorMessage("Error gathering IAM Users list", err.Error())
		return &IAMUsers{}, err
	}
	iam := make(IAMUsers, len(result.Users))
	for i, user := range result.Users {
		iam[i].Marshal(user)
	}
	iamList = new(IAMUsers)
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, ia := range iam {
			rIam := reflect.ValueOf(ia)
			for k := 0; k < rIam.NumField(); k++ {
				sVal := rIam.Field(k).String()
				if term.MatchString(sVal) {
					*iamList = append(*iamList, iam[i])
					continue Loop
				}
			}
		}
	} else {
		*iamList = append(*iamList, iam[:]...)
	}
	return iamList, nil
}
func GetIAMRole(name string) (IAMRole, error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	params := &iam.GetRoleInput{
		RoleName: aws.String(name),
	}
	resp, err := svc.GetRole(params)
	if err != nil {
		return IAMRole{}, err
	}
	role := new(IAMRole)
	role.Marshal(resp.Role)
	return *role, nil
}
func GetIAMRolePolicyNames(roleName string) ([]string, error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	params := &iam.ListRolePoliciesInput{
		RoleName: aws.String(roleName),
	}
	resp, err := svc.ListRolePolicies(params)
	if err != nil {
		return []string{}, err
	}
	return aws.StringValueSlice(resp.PolicyNames), nil
}
func GetIAMAttachedRolePolicyARNs(roleName string) ([]string, error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	params := &iam.ListAttachedRolePoliciesInput{
		RoleName: aws.String(roleName),
	}
	resp, err := svc.ListAttachedRolePolicies(params)
	if err != nil {
		return []string{}, err
	}
	policyArns := make([]string, len(resp.AttachedPolicies))
	for i, policy := range resp.AttachedPolicies {
		policyArns[i] = aws.StringValue(policy.PolicyArn)
	}
	return policyArns, nil
}
func GetIAMRoles(search string) (iamRoleList *IAMRoles, err error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	result, err := svc.ListRoles(&iam.ListRolesInput{})
	if err != nil {
		terminal.ShowErrorMessage("Error gathering IAM Roles list", err.Error())
		return &IAMRoles{}, err
	}
	iam := make(IAMRoles, len(result.Roles))
	for i, role := range result.Roles {
		iam[i].Marshal(role)
	}
	iamRoleList = new(IAMRoles)
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, ia := range iam {
			rIam := reflect.ValueOf(ia)
			for k := 0; k < rIam.NumField(); k++ {
				sVal := rIam.Field(k).String()
				if term.MatchString(sVal) {
					*iamRoleList = append(*iamRoleList, iam[i])
					continue Loop
				}
			}
		}
	} else {
		*iamRoleList = append(*iamRoleList, iam[:]...)
	}
	return iamRoleList, nil
}
func GetIAMRoleByName(roleName string) (iamRole IAMRole, err error) {
	iamRoles, err := GetIAMRoles("")
	if err != nil {
		return iamRole, nil
	}
	for _, role := range *iamRoles {
		if role.RoleName == roleName {
			return role, nil
		}
	}
	return iamRole, errors.New("No IAM Role found matching [" + roleName + "]!")
}
func GetIAMPolicyByName(policyName string) (iamPolicy IAMPolicy, err error) {
	iamPolicies, err := GetIAMPolicies("")
	if err != nil {
		return iamPolicy, nil
	}
	for _, policy := range *iamPolicies {
		if policy.PolicyName == policyName {
			return policy, nil
		}
	}
	return iamPolicy, errors.New("No IAM Policy found matching [" + policyName + "]!")
}
func GetIAMInstanceProfileByName(instanceProfileName string) (iamInstanceProfile IAMInstanceProfile, err error) {
	iamInstanceProfiles, err := GetIAMInstanceProfiles("")
	if err != nil {
		return iamInstanceProfile, nil
	}
	for _, profile := range *iamInstanceProfiles {
		if profile.ProfileName == instanceProfileName {
			return profile, nil
		}
	}
	return iamInstanceProfile, errors.New("No IAM Instance Profile found matching [" + instanceProfileName + "]!")
}
func GetIAMPolicyDocument(search string, version string) (IAMPolicyDocument, error) {
	policies, err := GetIAMPolicies(search)
	if err != nil {
		return IAMPolicyDocument{}, err
	}
	policyCount := len(*policies)
	if policyCount == 0 {
		return IAMPolicyDocument{}, errors.New("No IAM Policies found for the search term provided")
	} else if policyCount > 1 {
		policies.PrintTable()
		return IAMPolicyDocument{}, errors.New("Please limit your search term to just one Policy")
	}
	policy := (*policies)[0]
	if version == "" {
		version = policy.DefaultVersionId
	}
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	params := &iam.GetPolicyVersionInput{
		PolicyArn: aws.String(policy.Arn),
		VersionId: aws.String(version),
	}
	resp, err := svc.GetPolicyVersion(params)
	if err != nil {
		return IAMPolicyDocument{}, err
	}
	policyDocument := new(IAMPolicyDocument)
	policyDocument.Marshal(resp.PolicyVersion)
	return *policyDocument, nil
}
func GetIAMPolicyByARN(policyARN string) (iamPolicy *IAMPolicy, err error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	params := &iam.GetPolicyInput{
		PolicyArn: aws.String(policyARN),
	}
	result, err := svc.GetPolicy(params)
	if err != nil {
		terminal.ShowErrorMessage("Error fetching IAM Policy", err.Error())
		return &IAMPolicy{}, err
	}
	iamPolicy = new(IAMPolicy)
	iamPolicy.Marshal(result.Policy)
	return iamPolicy, nil
}
func GetIAMPolicies(search string) (iamPolicyList *IAMPolicies, err error) {
	sess := session.Must(session.NewSession())
	svc := iam.New(sess)
	result, err := svc.ListPolicies(&iam.ListPoliciesInput{})
	if err != nil {
		terminal.ShowErrorMessage("Error gathering IAM Policy list", err.Error())
		return &IAMPolicies{}, err
	}
	iam := make(IAMPolicies, len(result.Policies))
	for i, policy := range result.Policies {
		iam[i].Marshal(policy)
	}
	iamPolicyList = new(IAMPolicies)
	if search != "" {
		term := regexp.MustCompile(search)
	Loop:
		for i, ia := range iam {
			rIam := reflect.ValueOf(ia)
			for k := 0; k < rIam.NumField(); k++ {
				sVal := rIam.Field(k).String()
				if term.MatchString(sVal) {
					*iamPolicyList = append(*iamPolicyList, iam[i])
					continue Loop
				}
			}
		}
	} else {
		*iamPolicyList = append(*iamPolicyList, iam[:]...)
	}
	return iamPolicyList, nil
}