From 1150487ee85449d9434c73b5c9103288c1b46f99 Mon Sep 17 00:00:00 2001
From: Yury Tsarev <yury@upbound.io>
Date: Thu, 3 Feb 2022 13:57:30 +0100
Subject: [PATCH 1/4] InstanceProfile ACK generation

Regenerate without Region

Commit iam generator-config

make generate result

Setup Controller and Register CRD

Fix imports and compile

Regenerate not requiring InstanceProfileName within the spec

Fix externalname and readiness, provide example

Generate rolereference

Fix field capitalization

Hook into postCreate to call AddRoleToInstanceProfile

Handle deletion and update examples

Signed-off-by: Yury Tsarev <yury@upbound.io>
---
 Makefile                                      |    5 +-
 apis/aws.go                                   |    2 +
 apis/iam/generator-config.yaml                |   19 +
 apis/iam/v1alpha1/custom_types.go             |   19 +
 apis/iam/v1alpha1/zz_doc.go                   |   24 +
 apis/iam/v1alpha1/zz_enums.go                 |  209 +++
 apis/iam/v1alpha1/zz_generated.deepcopy.go    | 1519 +++++++++++++++++
 apis/iam/v1alpha1/zz_generated.managed.go     |   77 +
 apis/iam/v1alpha1/zz_generated.managedlist.go |   30 +
 apis/iam/v1alpha1/zz_generated.resolvers.go   |   53 +
 apis/iam/v1alpha1/zz_groupversion_info.go     |   41 +
 apis/iam/v1alpha1/zz_instance_profile.go      |  120 ++
 apis/iam/v1alpha1/zz_types.go                 |  523 ++++++
 examples/iam/instanceprofile.yaml             |   13 +
 examples/iam/roleforinstanceprofile.yaml      |   33 +
 ...am.aws.crossplane.io_instanceprofiles.yaml |  312 ++++
 pkg/controller/aws.go                         |    2 +
 pkg/controller/iam/instanceprofile/setup.go   |  110 ++
 .../iam/instanceprofile/zz_controller.go      |  314 ++++
 .../iam/instanceprofile/zz_conversions.go     |  197 +++
 20 files changed, 3620 insertions(+), 2 deletions(-)
 create mode 100644 apis/iam/generator-config.yaml
 create mode 100644 apis/iam/v1alpha1/custom_types.go
 create mode 100644 apis/iam/v1alpha1/zz_doc.go
 create mode 100644 apis/iam/v1alpha1/zz_enums.go
 create mode 100644 apis/iam/v1alpha1/zz_generated.deepcopy.go
 create mode 100644 apis/iam/v1alpha1/zz_generated.managed.go
 create mode 100644 apis/iam/v1alpha1/zz_generated.managedlist.go
 create mode 100644 apis/iam/v1alpha1/zz_generated.resolvers.go
 create mode 100644 apis/iam/v1alpha1/zz_groupversion_info.go
 create mode 100644 apis/iam/v1alpha1/zz_instance_profile.go
 create mode 100644 apis/iam/v1alpha1/zz_types.go
 create mode 100644 examples/iam/instanceprofile.yaml
 create mode 100644 examples/iam/roleforinstanceprofile.yaml
 create mode 100644 package/crds/iam.aws.crossplane.io_instanceprofiles.yaml
 create mode 100644 pkg/controller/iam/instanceprofile/setup.go
 create mode 100644 pkg/controller/iam/instanceprofile/zz_controller.go
 create mode 100644 pkg/controller/iam/instanceprofile/zz_conversions.go

diff --git a/Makefile b/Makefile
index 66730bc315..1d36ec0185 100644
--- a/Makefile
+++ b/Makefile
@@ -6,8 +6,9 @@ PROJECT_REPO := github.com/crossplane/$(PROJECT_NAME)
 
 PLATFORMS ?= linux_amd64 linux_arm64
 
+CODE_GENERATOR_REPO ?= https://github.com/aws-controllers-k8s/code-generator.git
 CODE_GENERATOR_COMMIT ?= f8c0f4711a91e50335450521e3c49673d135d56d
-GENERATED_SERVICES := $(shell find ./apis -type f -name generator-config.yaml | cut -d/ -f 3 | tr '\n' ' ')
+GENERATED_SERVICES := $(shell find ./apis/ -type f -name generator-config.yaml | cut -d/ -f 3 | tr '\n' ' ')
 
 # kind-related versions
 KIND_VERSION ?= v0.11.1
@@ -124,7 +125,7 @@ run: go.build
 # be in its root directory to call "go run" properly.
 services: $(GOIMPORTS)
 	@if [ ! -d "$(WORK_DIR)/code-generator" ]; then \
-		cd $(WORK_DIR) && git clone "https://github.com/aws-controllers-k8s/code-generator.git"; \
+		cd $(WORK_DIR) && git clone "$(CODE_GENERATOR_REPO)"; \
 	fi
 	@cd $(WORK_DIR)/code-generator && git fetch origin && git checkout $(CODE_GENERATOR_COMMIT)
 	@for svc in $(SERVICES); do \
diff --git a/apis/aws.go b/apis/aws.go
index fe3b7b5067..469bb7bebf 100644
--- a/apis/aws.go
+++ b/apis/aws.go
@@ -47,6 +47,7 @@ import (
 	elasticloadbalancingv1alpha1 "github.com/crossplane/provider-aws/apis/elasticloadbalancing/v1alpha1"
 	elbv2v1alpha1 "github.com/crossplane/provider-aws/apis/elbv2/v1alpha1"
 	gluev1alpha1 "github.com/crossplane/provider-aws/apis/glue/v1alpha1"
+	iamv1alpha1 "github.com/crossplane/provider-aws/apis/iam/v1alpha1"
 	iamv1beta1 "github.com/crossplane/provider-aws/apis/iam/v1beta1"
 	iotv1alpha1 "github.com/crossplane/provider-aws/apis/iot/v1alpha1"
 	kafkav1alpha1 "github.com/crossplane/provider-aws/apis/kafka/v1alpha1"
@@ -84,6 +85,7 @@ func init() {
 		databasev1beta1.SchemeBuilder.AddToScheme,
 		docdbv1alpha1.AddToScheme,
 		elasticloadbalancingv1alpha1.SchemeBuilder.AddToScheme,
+		iamv1alpha1.SchemeBuilder.AddToScheme,
 		iamv1beta1.SchemeBuilder.AddToScheme,
 		elasticachev1alpha1.SchemeBuilder.AddToScheme,
 		elbv2v1alpha1.SchemeBuilder.AddToScheme,
diff --git a/apis/iam/generator-config.yaml b/apis/iam/generator-config.yaml
new file mode 100644
index 0000000000..b6a8179147
--- /dev/null
+++ b/apis/iam/generator-config.yaml
@@ -0,0 +1,19 @@
+ignore:
+  resource_names:
+    - AccessKey
+    - AccountAlias
+    - Doc
+    - Group
+    - LoginProfile
+    - OpenIDConnectProvider
+    - Policy
+    - PolicyVersion
+    - Role
+    - SAMLProvider
+    - ServiceLinkedRole
+    - ServiceSpecificCredential
+    - User
+    - VirtualMFADevice
+  field_paths:
+    - CreateInstanceProfileInput.InstanceProfileName
+    - DeleteInstanceProfileInput.InstanceProfileName
diff --git a/apis/iam/v1alpha1/custom_types.go b/apis/iam/v1alpha1/custom_types.go
new file mode 100644
index 0000000000..a0e47c05ec
--- /dev/null
+++ b/apis/iam/v1alpha1/custom_types.go
@@ -0,0 +1,19 @@
+package v1alpha1
+
+import xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
+
+// CustomInstanceProfileParameters includes the custom fields of InstanceProfile.
+type CustomInstanceProfileParameters struct {
+	// Role is the ID for the Role to add to Instance Profile.
+	// +immutable
+	// +crossplane:generate:reference:type=github.com/crossplane/provider-aws/apis/iam/v1beta1.Role
+	Role *string `json:"role,omitempty"`
+
+	// RoleRef is a reference to an Role
+	// +optional
+	RoleRef *xpv1.Reference `json:"roleRef,omitempty"`
+
+	// RoleSelector selects references to Role
+	// +optional
+	RoleSelector *xpv1.Selector `json:"roleSelector,omitempty"`
+}
diff --git a/apis/iam/v1alpha1/zz_doc.go b/apis/iam/v1alpha1/zz_doc.go
new file mode 100644
index 0000000000..02c63402ed
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_doc.go
@@ -0,0 +1,24 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+// +kubebuilder:object:generate=true
+// Package v1alpha1 is the v1alpha1 version of the iam.aws.crossplane.io API.
+// +groupName=iam.aws.crossplane.io
+// +versionName=v1alpha1
+
+package v1alpha1
diff --git a/apis/iam/v1alpha1/zz_enums.go b/apis/iam/v1alpha1/zz_enums.go
new file mode 100644
index 0000000000..4feb5d42ac
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_enums.go
@@ -0,0 +1,209 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+package v1alpha1
+
+type AccessAdvisorUsageGranularityType string
+
+const (
+	AccessAdvisorUsageGranularityType_SERVICE_LEVEL AccessAdvisorUsageGranularityType = "SERVICE_LEVEL"
+	AccessAdvisorUsageGranularityType_ACTION_LEVEL  AccessAdvisorUsageGranularityType = "ACTION_LEVEL"
+)
+
+type AssignmentStatusType string
+
+const (
+	AssignmentStatusType_Assigned   AssignmentStatusType = "Assigned"
+	AssignmentStatusType_Unassigned AssignmentStatusType = "Unassigned"
+	AssignmentStatusType_Any        AssignmentStatusType = "Any"
+)
+
+type ContextKeyTypeEnum string
+
+const (
+	ContextKeyTypeEnum_string      ContextKeyTypeEnum = "string"
+	ContextKeyTypeEnum_stringList  ContextKeyTypeEnum = "stringList"
+	ContextKeyTypeEnum_numeric     ContextKeyTypeEnum = "numeric"
+	ContextKeyTypeEnum_numericList ContextKeyTypeEnum = "numericList"
+	ContextKeyTypeEnum_boolean     ContextKeyTypeEnum = "boolean"
+	ContextKeyTypeEnum_booleanList ContextKeyTypeEnum = "booleanList"
+	ContextKeyTypeEnum_ip          ContextKeyTypeEnum = "ip"
+	ContextKeyTypeEnum_ipList      ContextKeyTypeEnum = "ipList"
+	ContextKeyTypeEnum_binary      ContextKeyTypeEnum = "binary"
+	ContextKeyTypeEnum_binaryList  ContextKeyTypeEnum = "binaryList"
+	ContextKeyTypeEnum_date        ContextKeyTypeEnum = "date"
+	ContextKeyTypeEnum_dateList    ContextKeyTypeEnum = "dateList"
+)
+
+type DeletionTaskStatusType string
+
+const (
+	DeletionTaskStatusType_SUCCEEDED   DeletionTaskStatusType = "SUCCEEDED"
+	DeletionTaskStatusType_IN_PROGRESS DeletionTaskStatusType = "IN_PROGRESS"
+	DeletionTaskStatusType_FAILED      DeletionTaskStatusType = "FAILED"
+	DeletionTaskStatusType_NOT_STARTED DeletionTaskStatusType = "NOT_STARTED"
+)
+
+type EncodingType string
+
+const (
+	EncodingType_SSH EncodingType = "SSH"
+	EncodingType_PEM EncodingType = "PEM"
+)
+
+type EntityType string
+
+const (
+	EntityType_User               EntityType = "User"
+	EntityType_Role               EntityType = "Role"
+	EntityType_Group              EntityType = "Group"
+	EntityType_LocalManagedPolicy EntityType = "LocalManagedPolicy"
+	EntityType_AWSManagedPolicy   EntityType = "AWSManagedPolicy"
+)
+
+type GlobalEndpointTokenVersion string
+
+const (
+	GlobalEndpointTokenVersion_v1Token GlobalEndpointTokenVersion = "v1Token"
+	GlobalEndpointTokenVersion_v2Token GlobalEndpointTokenVersion = "v2Token"
+)
+
+type JobStatusType string
+
+const (
+	JobStatusType_IN_PROGRESS JobStatusType = "IN_PROGRESS"
+	JobStatusType_COMPLETED   JobStatusType = "COMPLETED"
+	JobStatusType_FAILED      JobStatusType = "FAILED"
+)
+
+type PermissionsBoundaryAttachmentType string
+
+const (
+	PermissionsBoundaryAttachmentType_PermissionsBoundaryPolicy PermissionsBoundaryAttachmentType = "PermissionsBoundaryPolicy"
+)
+
+type PolicyEvaluationDecisionType string
+
+const (
+	PolicyEvaluationDecisionType_allowed      PolicyEvaluationDecisionType = "allowed"
+	PolicyEvaluationDecisionType_explicitDeny PolicyEvaluationDecisionType = "explicitDeny"
+	PolicyEvaluationDecisionType_implicitDeny PolicyEvaluationDecisionType = "implicitDeny"
+)
+
+type PolicyOwnerEntityType string
+
+const (
+	PolicyOwnerEntityType_USER  PolicyOwnerEntityType = "USER"
+	PolicyOwnerEntityType_ROLE  PolicyOwnerEntityType = "ROLE"
+	PolicyOwnerEntityType_GROUP PolicyOwnerEntityType = "GROUP"
+)
+
+type PolicyScopeType string
+
+const (
+	PolicyScopeType_All   PolicyScopeType = "All"
+	PolicyScopeType_AWS   PolicyScopeType = "AWS"
+	PolicyScopeType_Local PolicyScopeType = "Local"
+)
+
+type PolicySourceType string
+
+const (
+	PolicySourceType_user         PolicySourceType = "user"
+	PolicySourceType_group        PolicySourceType = "group"
+	PolicySourceType_role         PolicySourceType = "role"
+	PolicySourceType_aws_managed  PolicySourceType = "aws-managed"
+	PolicySourceType_user_managed PolicySourceType = "user-managed"
+	PolicySourceType_resource     PolicySourceType = "resource"
+	PolicySourceType_none         PolicySourceType = "none"
+)
+
+type PolicyType string
+
+const (
+	PolicyType_INLINE  PolicyType = "INLINE"
+	PolicyType_MANAGED PolicyType = "MANAGED"
+)
+
+type PolicyUsageType string
+
+const (
+	PolicyUsageType_PermissionsPolicy   PolicyUsageType = "PermissionsPolicy"
+	PolicyUsageType_PermissionsBoundary PolicyUsageType = "PermissionsBoundary"
+)
+
+type ReportFormatType string
+
+const (
+	ReportFormatType_text_csv ReportFormatType = "text/csv"
+)
+
+type ReportStateType string
+
+const (
+	ReportStateType_STARTED    ReportStateType = "STARTED"
+	ReportStateType_INPROGRESS ReportStateType = "INPROGRESS"
+	ReportStateType_COMPLETE   ReportStateType = "COMPLETE"
+)
+
+type SortKeyType string
+
+const (
+	SortKeyType_SERVICE_NAMESPACE_ASCENDING        SortKeyType = "SERVICE_NAMESPACE_ASCENDING"
+	SortKeyType_SERVICE_NAMESPACE_DESCENDING       SortKeyType = "SERVICE_NAMESPACE_DESCENDING"
+	SortKeyType_LAST_AUTHENTICATED_TIME_ASCENDING  SortKeyType = "LAST_AUTHENTICATED_TIME_ASCENDING"
+	SortKeyType_LAST_AUTHENTICATED_TIME_DESCENDING SortKeyType = "LAST_AUTHENTICATED_TIME_DESCENDING"
+)
+
+type StatusType string
+
+const (
+	StatusType_Active   StatusType = "Active"
+	StatusType_Inactive StatusType = "Inactive"
+)
+
+type SummaryKeyType string
+
+const (
+	SummaryKeyType_Users                             SummaryKeyType = "Users"
+	SummaryKeyType_UsersQuota                        SummaryKeyType = "UsersQuota"
+	SummaryKeyType_Groups                            SummaryKeyType = "Groups"
+	SummaryKeyType_GroupsQuota                       SummaryKeyType = "GroupsQuota"
+	SummaryKeyType_ServerCertificates                SummaryKeyType = "ServerCertificates"
+	SummaryKeyType_ServerCertificatesQuota           SummaryKeyType = "ServerCertificatesQuota"
+	SummaryKeyType_UserPolicySizeQuota               SummaryKeyType = "UserPolicySizeQuota"
+	SummaryKeyType_GroupPolicySizeQuota              SummaryKeyType = "GroupPolicySizeQuota"
+	SummaryKeyType_GroupsPerUserQuota                SummaryKeyType = "GroupsPerUserQuota"
+	SummaryKeyType_SigningCertificatesPerUserQuota   SummaryKeyType = "SigningCertificatesPerUserQuota"
+	SummaryKeyType_AccessKeysPerUserQuota            SummaryKeyType = "AccessKeysPerUserQuota"
+	SummaryKeyType_MFADevices                        SummaryKeyType = "MFADevices"
+	SummaryKeyType_MFADevicesInUse                   SummaryKeyType = "MFADevicesInUse"
+	SummaryKeyType_AccountMFAEnabled                 SummaryKeyType = "AccountMFAEnabled"
+	SummaryKeyType_AccountAccessKeysPresent          SummaryKeyType = "AccountAccessKeysPresent"
+	SummaryKeyType_AccountSigningCertificatesPresent SummaryKeyType = "AccountSigningCertificatesPresent"
+	SummaryKeyType_AttachedPoliciesPerGroupQuota     SummaryKeyType = "AttachedPoliciesPerGroupQuota"
+	SummaryKeyType_AttachedPoliciesPerRoleQuota      SummaryKeyType = "AttachedPoliciesPerRoleQuota"
+	SummaryKeyType_AttachedPoliciesPerUserQuota      SummaryKeyType = "AttachedPoliciesPerUserQuota"
+	SummaryKeyType_Policies                          SummaryKeyType = "Policies"
+	SummaryKeyType_PoliciesQuota                     SummaryKeyType = "PoliciesQuota"
+	SummaryKeyType_PolicySizeQuota                   SummaryKeyType = "PolicySizeQuota"
+	SummaryKeyType_PolicyVersionsInUse               SummaryKeyType = "PolicyVersionsInUse"
+	SummaryKeyType_PolicyVersionsInUseQuota          SummaryKeyType = "PolicyVersionsInUseQuota"
+	SummaryKeyType_VersionsPerPolicyQuota            SummaryKeyType = "VersionsPerPolicyQuota"
+	SummaryKeyType_GlobalEndpointTokenVersion        SummaryKeyType = "GlobalEndpointTokenVersion"
+)
diff --git a/apis/iam/v1alpha1/zz_generated.deepcopy.go b/apis/iam/v1alpha1/zz_generated.deepcopy.go
new file mode 100644
index 0000000000..5cb6e13790
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_generated.deepcopy.go
@@ -0,0 +1,1519 @@
+//go:build !ignore_autogenerated
+// +build !ignore_autogenerated
+
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	"github.com/crossplane/crossplane-runtime/apis/common/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AccessDetail) DeepCopyInto(out *AccessDetail) {
+	*out = *in
+	if in.LastAuthenticatedTime != nil {
+		in, out := &in.LastAuthenticatedTime, &out.LastAuthenticatedTime
+		*out = (*in).DeepCopy()
+	}
+	if in.Region != nil {
+		in, out := &in.Region, &out.Region
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessDetail.
+func (in *AccessDetail) DeepCopy() *AccessDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(AccessDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AccessKey) DeepCopyInto(out *AccessKey) {
+	*out = *in
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessKey.
+func (in *AccessKey) DeepCopy() *AccessKey {
+	if in == nil {
+		return nil
+	}
+	out := new(AccessKey)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AccessKeyLastUsed) DeepCopyInto(out *AccessKeyLastUsed) {
+	*out = *in
+	if in.LastUsedDate != nil {
+		in, out := &in.LastUsedDate, &out.LastUsedDate
+		*out = (*in).DeepCopy()
+	}
+	if in.Region != nil {
+		in, out := &in.Region, &out.Region
+		*out = new(string)
+		**out = **in
+	}
+	if in.ServiceName != nil {
+		in, out := &in.ServiceName, &out.ServiceName
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessKeyLastUsed.
+func (in *AccessKeyLastUsed) DeepCopy() *AccessKeyLastUsed {
+	if in == nil {
+		return nil
+	}
+	out := new(AccessKeyLastUsed)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AccessKeyMetadata) DeepCopyInto(out *AccessKeyMetadata) {
+	*out = *in
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessKeyMetadata.
+func (in *AccessKeyMetadata) DeepCopy() *AccessKeyMetadata {
+	if in == nil {
+		return nil
+	}
+	out := new(AccessKeyMetadata)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AttachedPermissionsBoundary) DeepCopyInto(out *AttachedPermissionsBoundary) {
+	*out = *in
+	if in.PermissionsBoundaryARN != nil {
+		in, out := &in.PermissionsBoundaryARN, &out.PermissionsBoundaryARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.PermissionsBoundaryType != nil {
+		in, out := &in.PermissionsBoundaryType, &out.PermissionsBoundaryType
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttachedPermissionsBoundary.
+func (in *AttachedPermissionsBoundary) DeepCopy() *AttachedPermissionsBoundary {
+	if in == nil {
+		return nil
+	}
+	out := new(AttachedPermissionsBoundary)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AttachedPolicy) DeepCopyInto(out *AttachedPolicy) {
+	*out = *in
+	if in.PolicyARN != nil {
+		in, out := &in.PolicyARN, &out.PolicyARN
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttachedPolicy.
+func (in *AttachedPolicy) DeepCopy() *AttachedPolicy {
+	if in == nil {
+		return nil
+	}
+	out := new(AttachedPolicy)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CustomInstanceProfileParameters) DeepCopyInto(out *CustomInstanceProfileParameters) {
+	*out = *in
+	if in.Role != nil {
+		in, out := &in.Role, &out.Role
+		*out = new(string)
+		**out = **in
+	}
+	if in.RoleRef != nil {
+		in, out := &in.RoleRef, &out.RoleRef
+		*out = new(v1.Reference)
+		**out = **in
+	}
+	if in.RoleSelector != nil {
+		in, out := &in.RoleSelector, &out.RoleSelector
+		*out = new(v1.Selector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomInstanceProfileParameters.
+func (in *CustomInstanceProfileParameters) DeepCopy() *CustomInstanceProfileParameters {
+	if in == nil {
+		return nil
+	}
+	out := new(CustomInstanceProfileParameters)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EntityDetails) DeepCopyInto(out *EntityDetails) {
+	*out = *in
+	if in.LastAuthenticated != nil {
+		in, out := &in.LastAuthenticated, &out.LastAuthenticated
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EntityDetails.
+func (in *EntityDetails) DeepCopy() *EntityDetails {
+	if in == nil {
+		return nil
+	}
+	out := new(EntityDetails)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EntityInfo) DeepCopyInto(out *EntityInfo) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.ID != nil {
+		in, out := &in.ID, &out.ID
+		*out = new(string)
+		**out = **in
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EntityInfo.
+func (in *EntityInfo) DeepCopy() *EntityInfo {
+	if in == nil {
+		return nil
+	}
+	out := new(EntityInfo)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ErrorDetails) DeepCopyInto(out *ErrorDetails) {
+	*out = *in
+	if in.Code != nil {
+		in, out := &in.Code, &out.Code
+		*out = new(string)
+		**out = **in
+	}
+	if in.Message != nil {
+		in, out := &in.Message, &out.Message
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ErrorDetails.
+func (in *ErrorDetails) DeepCopy() *ErrorDetails {
+	if in == nil {
+		return nil
+	}
+	out := new(ErrorDetails)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Group) DeepCopyInto(out *Group) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.GroupID != nil {
+		in, out := &in.GroupID, &out.GroupID
+		*out = new(string)
+		**out = **in
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Group.
+func (in *Group) DeepCopy() *Group {
+	if in == nil {
+		return nil
+	}
+	out := new(Group)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GroupDetail) DeepCopyInto(out *GroupDetail) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.GroupID != nil {
+		in, out := &in.GroupID, &out.GroupID
+		*out = new(string)
+		**out = **in
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupDetail.
+func (in *GroupDetail) DeepCopy() *GroupDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(GroupDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfile) DeepCopyInto(out *InstanceProfile) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+	in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfile.
+func (in *InstanceProfile) DeepCopy() *InstanceProfile {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfile)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *InstanceProfile) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfileList) DeepCopyInto(out *InstanceProfileList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]InstanceProfile, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfileList.
+func (in *InstanceProfileList) DeepCopy() *InstanceProfileList {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfileList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *InstanceProfileList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfileObservation) DeepCopyInto(out *InstanceProfileObservation) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.InstanceProfileID != nil {
+		in, out := &in.InstanceProfileID, &out.InstanceProfileID
+		*out = new(string)
+		**out = **in
+	}
+	if in.InstanceProfileName != nil {
+		in, out := &in.InstanceProfileName, &out.InstanceProfileName
+		*out = new(string)
+		**out = **in
+	}
+	if in.Roles != nil {
+		in, out := &in.Roles, &out.Roles
+		*out = make([]*Role, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Role)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfileObservation.
+func (in *InstanceProfileObservation) DeepCopy() *InstanceProfileObservation {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfileObservation)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfileParameters) DeepCopyInto(out *InstanceProfileParameters) {
+	*out = *in
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+	in.CustomInstanceProfileParameters.DeepCopyInto(&out.CustomInstanceProfileParameters)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfileParameters.
+func (in *InstanceProfileParameters) DeepCopy() *InstanceProfileParameters {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfileParameters)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfileSpec) DeepCopyInto(out *InstanceProfileSpec) {
+	*out = *in
+	in.ResourceSpec.DeepCopyInto(&out.ResourceSpec)
+	in.ForProvider.DeepCopyInto(&out.ForProvider)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfileSpec.
+func (in *InstanceProfileSpec) DeepCopy() *InstanceProfileSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfileSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfileStatus) DeepCopyInto(out *InstanceProfileStatus) {
+	*out = *in
+	in.ResourceStatus.DeepCopyInto(&out.ResourceStatus)
+	in.AtProvider.DeepCopyInto(&out.AtProvider)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfileStatus.
+func (in *InstanceProfileStatus) DeepCopy() *InstanceProfileStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfileStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InstanceProfile_SDK) DeepCopyInto(out *InstanceProfile_SDK) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.InstanceProfileID != nil {
+		in, out := &in.InstanceProfileID, &out.InstanceProfileID
+		*out = new(string)
+		**out = **in
+	}
+	if in.InstanceProfileName != nil {
+		in, out := &in.InstanceProfileName, &out.InstanceProfileName
+		*out = new(string)
+		**out = **in
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.Roles != nil {
+		in, out := &in.Roles, &out.Roles
+		*out = make([]*Role, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Role)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceProfile_SDK.
+func (in *InstanceProfile_SDK) DeepCopy() *InstanceProfile_SDK {
+	if in == nil {
+		return nil
+	}
+	out := new(InstanceProfile_SDK)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LoginProfile) DeepCopyInto(out *LoginProfile) {
+	*out = *in
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.PasswordResetRequired != nil {
+		in, out := &in.PasswordResetRequired, &out.PasswordResetRequired
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginProfile.
+func (in *LoginProfile) DeepCopy() *LoginProfile {
+	if in == nil {
+		return nil
+	}
+	out := new(LoginProfile)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MFADevice) DeepCopyInto(out *MFADevice) {
+	*out = *in
+	if in.EnableDate != nil {
+		in, out := &in.EnableDate, &out.EnableDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MFADevice.
+func (in *MFADevice) DeepCopy() *MFADevice {
+	if in == nil {
+		return nil
+	}
+	out := new(MFADevice)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ManagedPolicyDetail) DeepCopyInto(out *ManagedPolicyDetail) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.IsAttachable != nil {
+		in, out := &in.IsAttachable, &out.IsAttachable
+		*out = new(bool)
+		**out = **in
+	}
+	if in.PolicyID != nil {
+		in, out := &in.PolicyID, &out.PolicyID
+		*out = new(string)
+		**out = **in
+	}
+	if in.UpdateDate != nil {
+		in, out := &in.UpdateDate, &out.UpdateDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedPolicyDetail.
+func (in *ManagedPolicyDetail) DeepCopy() *ManagedPolicyDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(ManagedPolicyDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OpenIDConnectProviderListEntry) DeepCopyInto(out *OpenIDConnectProviderListEntry) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenIDConnectProviderListEntry.
+func (in *OpenIDConnectProviderListEntry) DeepCopy() *OpenIDConnectProviderListEntry {
+	if in == nil {
+		return nil
+	}
+	out := new(OpenIDConnectProviderListEntry)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OrganizationsDecisionDetail) DeepCopyInto(out *OrganizationsDecisionDetail) {
+	*out = *in
+	if in.AllowedByOrganizations != nil {
+		in, out := &in.AllowedByOrganizations, &out.AllowedByOrganizations
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OrganizationsDecisionDetail.
+func (in *OrganizationsDecisionDetail) DeepCopy() *OrganizationsDecisionDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(OrganizationsDecisionDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PasswordPolicy) DeepCopyInto(out *PasswordPolicy) {
+	*out = *in
+	if in.AllowUsersToChangePassword != nil {
+		in, out := &in.AllowUsersToChangePassword, &out.AllowUsersToChangePassword
+		*out = new(bool)
+		**out = **in
+	}
+	if in.ExpirePasswords != nil {
+		in, out := &in.ExpirePasswords, &out.ExpirePasswords
+		*out = new(bool)
+		**out = **in
+	}
+	if in.RequireLowercaseCharacters != nil {
+		in, out := &in.RequireLowercaseCharacters, &out.RequireLowercaseCharacters
+		*out = new(bool)
+		**out = **in
+	}
+	if in.RequireNumbers != nil {
+		in, out := &in.RequireNumbers, &out.RequireNumbers
+		*out = new(bool)
+		**out = **in
+	}
+	if in.RequireSymbols != nil {
+		in, out := &in.RequireSymbols, &out.RequireSymbols
+		*out = new(bool)
+		**out = **in
+	}
+	if in.RequireUppercaseCharacters != nil {
+		in, out := &in.RequireUppercaseCharacters, &out.RequireUppercaseCharacters
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PasswordPolicy.
+func (in *PasswordPolicy) DeepCopy() *PasswordPolicy {
+	if in == nil {
+		return nil
+	}
+	out := new(PasswordPolicy)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PermissionsBoundaryDecisionDetail) DeepCopyInto(out *PermissionsBoundaryDecisionDetail) {
+	*out = *in
+	if in.AllowedByPermissionsBoundary != nil {
+		in, out := &in.AllowedByPermissionsBoundary, &out.AllowedByPermissionsBoundary
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PermissionsBoundaryDecisionDetail.
+func (in *PermissionsBoundaryDecisionDetail) DeepCopy() *PermissionsBoundaryDecisionDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(PermissionsBoundaryDecisionDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Policy) DeepCopyInto(out *Policy) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.IsAttachable != nil {
+		in, out := &in.IsAttachable, &out.IsAttachable
+		*out = new(bool)
+		**out = **in
+	}
+	if in.PolicyID != nil {
+		in, out := &in.PolicyID, &out.PolicyID
+		*out = new(string)
+		**out = **in
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+	if in.UpdateDate != nil {
+		in, out := &in.UpdateDate, &out.UpdateDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Policy.
+func (in *Policy) DeepCopy() *Policy {
+	if in == nil {
+		return nil
+	}
+	out := new(Policy)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyDetail) DeepCopyInto(out *PolicyDetail) {
+	*out = *in
+	if in.PolicyDocument != nil {
+		in, out := &in.PolicyDocument, &out.PolicyDocument
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyDetail.
+func (in *PolicyDetail) DeepCopy() *PolicyDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyGrantingServiceAccess) DeepCopyInto(out *PolicyGrantingServiceAccess) {
+	*out = *in
+	if in.PolicyARN != nil {
+		in, out := &in.PolicyARN, &out.PolicyARN
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyGrantingServiceAccess.
+func (in *PolicyGrantingServiceAccess) DeepCopy() *PolicyGrantingServiceAccess {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyGrantingServiceAccess)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyGroup) DeepCopyInto(out *PolicyGroup) {
+	*out = *in
+	if in.GroupID != nil {
+		in, out := &in.GroupID, &out.GroupID
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyGroup.
+func (in *PolicyGroup) DeepCopy() *PolicyGroup {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyGroup)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyRole) DeepCopyInto(out *PolicyRole) {
+	*out = *in
+	if in.RoleID != nil {
+		in, out := &in.RoleID, &out.RoleID
+		*out = new(string)
+		**out = **in
+	}
+	if in.RoleName != nil {
+		in, out := &in.RoleName, &out.RoleName
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyRole.
+func (in *PolicyRole) DeepCopy() *PolicyRole {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyRole)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyUser) DeepCopyInto(out *PolicyUser) {
+	*out = *in
+	if in.UserID != nil {
+		in, out := &in.UserID, &out.UserID
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyUser.
+func (in *PolicyUser) DeepCopy() *PolicyUser {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyUser)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyVersion) DeepCopyInto(out *PolicyVersion) {
+	*out = *in
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.Document != nil {
+		in, out := &in.Document, &out.Document
+		*out = new(string)
+		**out = **in
+	}
+	if in.IsDefaultVersion != nil {
+		in, out := &in.IsDefaultVersion, &out.IsDefaultVersion
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyVersion.
+func (in *PolicyVersion) DeepCopy() *PolicyVersion {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyVersion)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Role) DeepCopyInto(out *Role) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.AssumeRolePolicyDocument != nil {
+		in, out := &in.AssumeRolePolicyDocument, &out.AssumeRolePolicyDocument
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.Description != nil {
+		in, out := &in.Description, &out.Description
+		*out = new(string)
+		**out = **in
+	}
+	if in.MaxSessionDuration != nil {
+		in, out := &in.MaxSessionDuration, &out.MaxSessionDuration
+		*out = new(int64)
+		**out = **in
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.PermissionsBoundary != nil {
+		in, out := &in.PermissionsBoundary, &out.PermissionsBoundary
+		*out = new(AttachedPermissionsBoundary)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.RoleID != nil {
+		in, out := &in.RoleID, &out.RoleID
+		*out = new(string)
+		**out = **in
+	}
+	if in.RoleLastUsed != nil {
+		in, out := &in.RoleLastUsed, &out.RoleLastUsed
+		*out = new(RoleLastUsed)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.RoleName != nil {
+		in, out := &in.RoleName, &out.RoleName
+		*out = new(string)
+		**out = **in
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Role.
+func (in *Role) DeepCopy() *Role {
+	if in == nil {
+		return nil
+	}
+	out := new(Role)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RoleDetail) DeepCopyInto(out *RoleDetail) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.AssumeRolePolicyDocument != nil {
+		in, out := &in.AssumeRolePolicyDocument, &out.AssumeRolePolicyDocument
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.InstanceProfileList != nil {
+		in, out := &in.InstanceProfileList, &out.InstanceProfileList
+		*out = make([]*InstanceProfile_SDK, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(InstanceProfile_SDK)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.PermissionsBoundary != nil {
+		in, out := &in.PermissionsBoundary, &out.PermissionsBoundary
+		*out = new(AttachedPermissionsBoundary)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.RoleID != nil {
+		in, out := &in.RoleID, &out.RoleID
+		*out = new(string)
+		**out = **in
+	}
+	if in.RoleLastUsed != nil {
+		in, out := &in.RoleLastUsed, &out.RoleLastUsed
+		*out = new(RoleLastUsed)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.RoleName != nil {
+		in, out := &in.RoleName, &out.RoleName
+		*out = new(string)
+		**out = **in
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleDetail.
+func (in *RoleDetail) DeepCopy() *RoleDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(RoleDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RoleLastUsed) DeepCopyInto(out *RoleLastUsed) {
+	*out = *in
+	if in.LastUsedDate != nil {
+		in, out := &in.LastUsedDate, &out.LastUsedDate
+		*out = (*in).DeepCopy()
+	}
+	if in.Region != nil {
+		in, out := &in.Region, &out.Region
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleLastUsed.
+func (in *RoleLastUsed) DeepCopy() *RoleLastUsed {
+	if in == nil {
+		return nil
+	}
+	out := new(RoleLastUsed)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SAMLProviderListEntry) DeepCopyInto(out *SAMLProviderListEntry) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.ValidUntil != nil {
+		in, out := &in.ValidUntil, &out.ValidUntil
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SAMLProviderListEntry.
+func (in *SAMLProviderListEntry) DeepCopy() *SAMLProviderListEntry {
+	if in == nil {
+		return nil
+	}
+	out := new(SAMLProviderListEntry)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SSHPublicKey) DeepCopyInto(out *SSHPublicKey) {
+	*out = *in
+	if in.UploadDate != nil {
+		in, out := &in.UploadDate, &out.UploadDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSHPublicKey.
+func (in *SSHPublicKey) DeepCopy() *SSHPublicKey {
+	if in == nil {
+		return nil
+	}
+	out := new(SSHPublicKey)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SSHPublicKeyMetadata) DeepCopyInto(out *SSHPublicKeyMetadata) {
+	*out = *in
+	if in.UploadDate != nil {
+		in, out := &in.UploadDate, &out.UploadDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSHPublicKeyMetadata.
+func (in *SSHPublicKeyMetadata) DeepCopy() *SSHPublicKeyMetadata {
+	if in == nil {
+		return nil
+	}
+	out := new(SSHPublicKeyMetadata)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ServerCertificate) DeepCopyInto(out *ServerCertificate) {
+	*out = *in
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerCertificate.
+func (in *ServerCertificate) DeepCopy() *ServerCertificate {
+	if in == nil {
+		return nil
+	}
+	out := new(ServerCertificate)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ServerCertificateMetadata) DeepCopyInto(out *ServerCertificateMetadata) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.Expiration != nil {
+		in, out := &in.Expiration, &out.Expiration
+		*out = (*in).DeepCopy()
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.ServerCertificateID != nil {
+		in, out := &in.ServerCertificateID, &out.ServerCertificateID
+		*out = new(string)
+		**out = **in
+	}
+	if in.UploadDate != nil {
+		in, out := &in.UploadDate, &out.UploadDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerCertificateMetadata.
+func (in *ServerCertificateMetadata) DeepCopy() *ServerCertificateMetadata {
+	if in == nil {
+		return nil
+	}
+	out := new(ServerCertificateMetadata)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ServiceLastAccessed) DeepCopyInto(out *ServiceLastAccessed) {
+	*out = *in
+	if in.LastAuthenticated != nil {
+		in, out := &in.LastAuthenticated, &out.LastAuthenticated
+		*out = (*in).DeepCopy()
+	}
+	if in.LastAuthenticatedEntity != nil {
+		in, out := &in.LastAuthenticatedEntity, &out.LastAuthenticatedEntity
+		*out = new(string)
+		**out = **in
+	}
+	if in.LastAuthenticatedRegion != nil {
+		in, out := &in.LastAuthenticatedRegion, &out.LastAuthenticatedRegion
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceLastAccessed.
+func (in *ServiceLastAccessed) DeepCopy() *ServiceLastAccessed {
+	if in == nil {
+		return nil
+	}
+	out := new(ServiceLastAccessed)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ServiceSpecificCredential) DeepCopyInto(out *ServiceSpecificCredential) {
+	*out = *in
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpecificCredential.
+func (in *ServiceSpecificCredential) DeepCopy() *ServiceSpecificCredential {
+	if in == nil {
+		return nil
+	}
+	out := new(ServiceSpecificCredential)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ServiceSpecificCredentialMetadata) DeepCopyInto(out *ServiceSpecificCredentialMetadata) {
+	*out = *in
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpecificCredentialMetadata.
+func (in *ServiceSpecificCredentialMetadata) DeepCopy() *ServiceSpecificCredentialMetadata {
+	if in == nil {
+		return nil
+	}
+	out := new(ServiceSpecificCredentialMetadata)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SigningCertificate) DeepCopyInto(out *SigningCertificate) {
+	*out = *in
+	if in.UploadDate != nil {
+		in, out := &in.UploadDate, &out.UploadDate
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SigningCertificate.
+func (in *SigningCertificate) DeepCopy() *SigningCertificate {
+	if in == nil {
+		return nil
+	}
+	out := new(SigningCertificate)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Tag) DeepCopyInto(out *Tag) {
+	*out = *in
+	if in.Key != nil {
+		in, out := &in.Key, &out.Key
+		*out = new(string)
+		**out = **in
+	}
+	if in.Value != nil {
+		in, out := &in.Value, &out.Value
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tag.
+func (in *Tag) DeepCopy() *Tag {
+	if in == nil {
+		return nil
+	}
+	out := new(Tag)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *TrackedActionLastAccessed) DeepCopyInto(out *TrackedActionLastAccessed) {
+	*out = *in
+	if in.ActionName != nil {
+		in, out := &in.ActionName, &out.ActionName
+		*out = new(string)
+		**out = **in
+	}
+	if in.LastAccessedEntity != nil {
+		in, out := &in.LastAccessedEntity, &out.LastAccessedEntity
+		*out = new(string)
+		**out = **in
+	}
+	if in.LastAccessedRegion != nil {
+		in, out := &in.LastAccessedRegion, &out.LastAccessedRegion
+		*out = new(string)
+		**out = **in
+	}
+	if in.LastAccessedTime != nil {
+		in, out := &in.LastAccessedTime, &out.LastAccessedTime
+		*out = (*in).DeepCopy()
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrackedActionLastAccessed.
+func (in *TrackedActionLastAccessed) DeepCopy() *TrackedActionLastAccessed {
+	if in == nil {
+		return nil
+	}
+	out := new(TrackedActionLastAccessed)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *User) DeepCopyInto(out *User) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.PasswordLastUsed != nil {
+		in, out := &in.PasswordLastUsed, &out.PasswordLastUsed
+		*out = (*in).DeepCopy()
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.PermissionsBoundary != nil {
+		in, out := &in.PermissionsBoundary, &out.PermissionsBoundary
+		*out = new(AttachedPermissionsBoundary)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+	if in.UserID != nil {
+		in, out := &in.UserID, &out.UserID
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new User.
+func (in *User) DeepCopy() *User {
+	if in == nil {
+		return nil
+	}
+	out := new(User)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *UserDetail) DeepCopyInto(out *UserDetail) {
+	*out = *in
+	if in.ARN != nil {
+		in, out := &in.ARN, &out.ARN
+		*out = new(string)
+		**out = **in
+	}
+	if in.CreateDate != nil {
+		in, out := &in.CreateDate, &out.CreateDate
+		*out = (*in).DeepCopy()
+	}
+	if in.Path != nil {
+		in, out := &in.Path, &out.Path
+		*out = new(string)
+		**out = **in
+	}
+	if in.PermissionsBoundary != nil {
+		in, out := &in.PermissionsBoundary, &out.PermissionsBoundary
+		*out = new(AttachedPermissionsBoundary)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+	if in.UserID != nil {
+		in, out := &in.UserID, &out.UserID
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserDetail.
+func (in *UserDetail) DeepCopy() *UserDetail {
+	if in == nil {
+		return nil
+	}
+	out := new(UserDetail)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VirtualMFADevice) DeepCopyInto(out *VirtualMFADevice) {
+	*out = *in
+	if in.EnableDate != nil {
+		in, out := &in.EnableDate, &out.EnableDate
+		*out = (*in).DeepCopy()
+	}
+	if in.Tags != nil {
+		in, out := &in.Tags, &out.Tags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				(*in).DeepCopyInto(*out)
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualMFADevice.
+func (in *VirtualMFADevice) DeepCopy() *VirtualMFADevice {
+	if in == nil {
+		return nil
+	}
+	out := new(VirtualMFADevice)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/apis/iam/v1alpha1/zz_generated.managed.go b/apis/iam/v1alpha1/zz_generated.managed.go
new file mode 100644
index 0000000000..3bd1f72b38
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_generated.managed.go
@@ -0,0 +1,77 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by angryjet. DO NOT EDIT.
+
+package v1alpha1
+
+import xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
+
+// GetCondition of this InstanceProfile.
+func (mg *InstanceProfile) GetCondition(ct xpv1.ConditionType) xpv1.Condition {
+	return mg.Status.GetCondition(ct)
+}
+
+// GetDeletionPolicy of this InstanceProfile.
+func (mg *InstanceProfile) GetDeletionPolicy() xpv1.DeletionPolicy {
+	return mg.Spec.DeletionPolicy
+}
+
+// GetProviderConfigReference of this InstanceProfile.
+func (mg *InstanceProfile) GetProviderConfigReference() *xpv1.Reference {
+	return mg.Spec.ProviderConfigReference
+}
+
+/*
+GetProviderReference of this InstanceProfile.
+Deprecated: Use GetProviderConfigReference.
+*/
+func (mg *InstanceProfile) GetProviderReference() *xpv1.Reference {
+	return mg.Spec.ProviderReference
+}
+
+// GetWriteConnectionSecretToReference of this InstanceProfile.
+func (mg *InstanceProfile) GetWriteConnectionSecretToReference() *xpv1.SecretReference {
+	return mg.Spec.WriteConnectionSecretToReference
+}
+
+// SetConditions of this InstanceProfile.
+func (mg *InstanceProfile) SetConditions(c ...xpv1.Condition) {
+	mg.Status.SetConditions(c...)
+}
+
+// SetDeletionPolicy of this InstanceProfile.
+func (mg *InstanceProfile) SetDeletionPolicy(r xpv1.DeletionPolicy) {
+	mg.Spec.DeletionPolicy = r
+}
+
+// SetProviderConfigReference of this InstanceProfile.
+func (mg *InstanceProfile) SetProviderConfigReference(r *xpv1.Reference) {
+	mg.Spec.ProviderConfigReference = r
+}
+
+/*
+SetProviderReference of this InstanceProfile.
+Deprecated: Use SetProviderConfigReference.
+*/
+func (mg *InstanceProfile) SetProviderReference(r *xpv1.Reference) {
+	mg.Spec.ProviderReference = r
+}
+
+// SetWriteConnectionSecretToReference of this InstanceProfile.
+func (mg *InstanceProfile) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) {
+	mg.Spec.WriteConnectionSecretToReference = r
+}
diff --git a/apis/iam/v1alpha1/zz_generated.managedlist.go b/apis/iam/v1alpha1/zz_generated.managedlist.go
new file mode 100644
index 0000000000..776f76656d
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_generated.managedlist.go
@@ -0,0 +1,30 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by angryjet. DO NOT EDIT.
+
+package v1alpha1
+
+import resource "github.com/crossplane/crossplane-runtime/pkg/resource"
+
+// GetItems of this InstanceProfileList.
+func (l *InstanceProfileList) GetItems() []resource.Managed {
+	items := make([]resource.Managed, len(l.Items))
+	for i := range l.Items {
+		items[i] = &l.Items[i]
+	}
+	return items
+}
diff --git a/apis/iam/v1alpha1/zz_generated.resolvers.go b/apis/iam/v1alpha1/zz_generated.resolvers.go
new file mode 100644
index 0000000000..25688482e9
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_generated.resolvers.go
@@ -0,0 +1,53 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by angryjet. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	"context"
+	reference "github.com/crossplane/crossplane-runtime/pkg/reference"
+	v1beta1 "github.com/crossplane/provider-aws/apis/iam/v1beta1"
+	errors "github.com/pkg/errors"
+	client "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+// ResolveReferences of this InstanceProfile.
+func (mg *InstanceProfile) ResolveReferences(ctx context.Context, c client.Reader) error {
+	r := reference.NewAPIResolver(c, mg)
+
+	var rsp reference.ResolutionResponse
+	var err error
+
+	rsp, err = r.Resolve(ctx, reference.ResolutionRequest{
+		CurrentValue: reference.FromPtrValue(mg.Spec.ForProvider.CustomInstanceProfileParameters.Role),
+		Extract:      reference.ExternalName(),
+		Reference:    mg.Spec.ForProvider.CustomInstanceProfileParameters.RoleRef,
+		Selector:     mg.Spec.ForProvider.CustomInstanceProfileParameters.RoleSelector,
+		To: reference.To{
+			List:    &v1beta1.RoleList{},
+			Managed: &v1beta1.Role{},
+		},
+	})
+	if err != nil {
+		return errors.Wrap(err, "mg.Spec.ForProvider.CustomInstanceProfileParameters.Role")
+	}
+	mg.Spec.ForProvider.CustomInstanceProfileParameters.Role = reference.ToPtrValue(rsp.ResolvedValue)
+	mg.Spec.ForProvider.CustomInstanceProfileParameters.RoleRef = rsp.ResolvedReference
+
+	return nil
+}
diff --git a/apis/iam/v1alpha1/zz_groupversion_info.go b/apis/iam/v1alpha1/zz_groupversion_info.go
new file mode 100644
index 0000000000..ae316dee0b
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_groupversion_info.go
@@ -0,0 +1,41 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"sigs.k8s.io/controller-runtime/pkg/scheme"
+)
+
+// Package type metadata.
+const (
+	CRDGroup   = "iam.aws.crossplane.io"
+	CRDVersion = "v1alpha1"
+)
+
+var (
+	// GroupVersion is the API Group Version used to register the objects
+	GroupVersion = schema.GroupVersion{Group: CRDGroup, Version: CRDVersion}
+
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme
+	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
+
+	// AddToScheme adds the types in this group-version to the given scheme.
+	AddToScheme = SchemeBuilder.AddToScheme
+)
diff --git a/apis/iam/v1alpha1/zz_instance_profile.go b/apis/iam/v1alpha1/zz_instance_profile.go
new file mode 100644
index 0000000000..aaf6705f48
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_instance_profile.go
@@ -0,0 +1,120 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// InstanceProfileParameters defines the desired state of InstanceProfile
+type InstanceProfileParameters struct {
+	// The path to the instance profile. For more information about paths, see IAM
+	// Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html)
+	// in the IAM User Guide.
+	//
+	// This parameter is optional. If it is not included, it defaults to a slash
+	// (/).
+	//
+	// This parameter allows (through its regex pattern (http://wikipedia.org/wiki/regex))
+	// a string of characters consisting of either a forward slash (/) by itself
+	// or a string that must begin and end with forward slashes. In addition, it
+	// can contain any ASCII character from the ! (\u0021) through the DEL character
+	// (\u007F), including most punctuation characters, digits, and upper and lowercased
+	// letters.
+	Path *string `json:"path,omitempty"`
+	// A list of tags that you want to attach to the newly created IAM instance
+	// profile. Each tag consists of a key name and an associated value. For more
+	// information about tagging, see Tagging IAM resources (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html)
+	// in the IAM User Guide.
+	//
+	// If any one of the tags is invalid or if you exceed the allowed maximum number
+	// of tags, then the entire request fails and the resource is not created.
+	Tags                            []*Tag `json:"tags,omitempty"`
+	CustomInstanceProfileParameters `json:",inline"`
+}
+
+// InstanceProfileSpec defines the desired state of InstanceProfile
+type InstanceProfileSpec struct {
+	xpv1.ResourceSpec `json:",inline"`
+	ForProvider       InstanceProfileParameters `json:"forProvider"`
+}
+
+// InstanceProfileObservation defines the observed state of InstanceProfile
+type InstanceProfileObservation struct {
+	// The Amazon Resource Name (ARN) specifying the instance profile. For more
+	// information about ARNs and how to use them in policies, see IAM identifiers
+	// (https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html)
+	// in the IAM User Guide.
+	ARN *string `json:"arn,omitempty"`
+	// The date when the instance profile was created.
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+	// The stable and unique string identifying the instance profile. For more information
+	// about IDs, see IAM identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html)
+	// in the IAM User Guide.
+	InstanceProfileID *string `json:"instanceProfileID,omitempty"`
+	// The name identifying the instance profile.
+	InstanceProfileName *string `json:"instanceProfileName,omitempty"`
+	// The role associated with the instance profile.
+	Roles []*Role `json:"roles,omitempty"`
+}
+
+// InstanceProfileStatus defines the observed state of InstanceProfile.
+type InstanceProfileStatus struct {
+	xpv1.ResourceStatus `json:",inline"`
+	AtProvider          InstanceProfileObservation `json:"atProvider,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// InstanceProfile is the Schema for the InstanceProfiles API
+// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
+// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status"
+// +kubebuilder:printcolumn:name="EXTERNAL-NAME",type="string",JSONPath=".metadata.annotations.crossplane\\.io/external-name"
+// +kubebuilder:subresource:status
+// +kubebuilder:storageversion
+// +kubebuilder:resource:scope=Cluster,categories={crossplane,managed,aws}
+type InstanceProfile struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+	Spec              InstanceProfileSpec   `json:"spec"`
+	Status            InstanceProfileStatus `json:"status,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// InstanceProfileList contains a list of InstanceProfiles
+type InstanceProfileList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []InstanceProfile `json:"items"`
+}
+
+// Repository type metadata.
+var (
+	InstanceProfileKind             = "InstanceProfile"
+	InstanceProfileGroupKind        = schema.GroupKind{Group: CRDGroup, Kind: InstanceProfileKind}.String()
+	InstanceProfileKindAPIVersion   = InstanceProfileKind + "." + GroupVersion.String()
+	InstanceProfileGroupVersionKind = GroupVersion.WithKind(InstanceProfileKind)
+)
+
+func init() {
+	SchemeBuilder.Register(&InstanceProfile{}, &InstanceProfileList{})
+}
diff --git a/apis/iam/v1alpha1/zz_types.go b/apis/iam/v1alpha1/zz_types.go
new file mode 100644
index 0000000000..e6bb8e3793
--- /dev/null
+++ b/apis/iam/v1alpha1/zz_types.go
@@ -0,0 +1,523 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// Hack to avoid import errors during build...
+var (
+	_ = &metav1.Time{}
+)
+
+// +kubebuilder:skipversion
+type AccessDetail struct {
+	LastAuthenticatedTime *metav1.Time `json:"lastAuthenticatedTime,omitempty"`
+
+	Region *string `json:"region,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type AccessKey struct {
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type AccessKeyLastUsed struct {
+	LastUsedDate *metav1.Time `json:"lastUsedDate,omitempty"`
+
+	Region *string `json:"region,omitempty"`
+
+	ServiceName *string `json:"serviceName,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type AccessKeyMetadata struct {
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type AttachedPermissionsBoundary struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	PermissionsBoundaryARN *string `json:"permissionsBoundaryARN,omitempty"`
+
+	PermissionsBoundaryType *string `json:"permissionsBoundaryType,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type AttachedPolicy struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	PolicyARN *string `json:"policyARN,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type EntityDetails struct {
+	LastAuthenticated *metav1.Time `json:"lastAuthenticated,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type EntityInfo struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	ID *string `json:"id,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ErrorDetails struct {
+	Code *string `json:"code,omitempty"`
+
+	Message *string `json:"message,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type Group struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	GroupID *string `json:"groupID,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type GroupDetail struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	GroupID *string `json:"groupID,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type InstanceProfile_SDK struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	InstanceProfileID *string `json:"instanceProfileID,omitempty"`
+
+	InstanceProfileName *string `json:"instanceProfileName,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+	// Contains a list of IAM roles.
+	//
+	// This data type is used as a response element in the ListRoles operation.
+	Roles []*Role `json:"roles,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type LoginProfile struct {
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	PasswordResetRequired *bool `json:"passwordResetRequired,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type MFADevice struct {
+	EnableDate *metav1.Time `json:"enableDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ManagedPolicyDetail struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	IsAttachable *bool `json:"isAttachable,omitempty"`
+
+	PolicyID *string `json:"policyID,omitempty"`
+
+	UpdateDate *metav1.Time `json:"updateDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type OpenIDConnectProviderListEntry struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type OrganizationsDecisionDetail struct {
+	AllowedByOrganizations *bool `json:"allowedByOrganizations,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PasswordPolicy struct {
+	AllowUsersToChangePassword *bool `json:"allowUsersToChangePassword,omitempty"`
+
+	ExpirePasswords *bool `json:"expirePasswords,omitempty"`
+
+	RequireLowercaseCharacters *bool `json:"requireLowercaseCharacters,omitempty"`
+
+	RequireNumbers *bool `json:"requireNumbers,omitempty"`
+
+	RequireSymbols *bool `json:"requireSymbols,omitempty"`
+
+	RequireUppercaseCharacters *bool `json:"requireUppercaseCharacters,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PermissionsBoundaryDecisionDetail struct {
+	AllowedByPermissionsBoundary *bool `json:"allowedByPermissionsBoundary,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type Policy struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	IsAttachable *bool `json:"isAttachable,omitempty"`
+
+	PolicyID *string `json:"policyID,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+
+	UpdateDate *metav1.Time `json:"updateDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PolicyDetail struct {
+	PolicyDocument *string `json:"policyDocument,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PolicyGrantingServiceAccess struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	PolicyARN *string `json:"policyARN,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PolicyGroup struct {
+	GroupID *string `json:"groupID,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PolicyRole struct {
+	RoleID *string `json:"roleID,omitempty"`
+
+	RoleName *string `json:"roleName,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PolicyUser struct {
+	UserID *string `json:"userID,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type PolicyVersion struct {
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	Document *string `json:"document,omitempty"`
+
+	IsDefaultVersion *bool `json:"isDefaultVersion,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type Role struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	AssumeRolePolicyDocument *string `json:"assumeRolePolicyDocument,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	Description *string `json:"description,omitempty"`
+
+	MaxSessionDuration *int64 `json:"maxSessionDuration,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+	// Contains information about an attached permissions boundary.
+	//
+	// An attached permissions boundary is a managed policy that has been attached
+	// to a user or role to set the permissions boundary.
+	//
+	// For more information about permissions boundaries, see Permissions boundaries
+	// for IAM identities (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
+	// in the IAM User Guide.
+	PermissionsBoundary *AttachedPermissionsBoundary `json:"permissionsBoundary,omitempty"`
+
+	RoleID *string `json:"roleID,omitempty"`
+	// Contains information about the last time that an IAM role was used. This
+	// includes the date and time and the Region in which the role was last used.
+	// Activity is only reported for the trailing 400 days. This period can be shorter
+	// if your Region began supporting these features within the last year. The
+	// role might have been used more than 400 days ago. For more information, see
+	// Regions where data is tracked (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period)
+	// in the IAM User Guide.
+	//
+	// This data type is returned as a response element in the GetRole and GetAccountAuthorizationDetails
+	// operations.
+	RoleLastUsed *RoleLastUsed `json:"roleLastUsed,omitempty"`
+
+	RoleName *string `json:"roleName,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type RoleDetail struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	AssumeRolePolicyDocument *string `json:"assumeRolePolicyDocument,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+	// Contains a list of instance profiles.
+	InstanceProfileList []*InstanceProfile_SDK `json:"instanceProfileList,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+	// Contains information about an attached permissions boundary.
+	//
+	// An attached permissions boundary is a managed policy that has been attached
+	// to a user or role to set the permissions boundary.
+	//
+	// For more information about permissions boundaries, see Permissions boundaries
+	// for IAM identities (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
+	// in the IAM User Guide.
+	PermissionsBoundary *AttachedPermissionsBoundary `json:"permissionsBoundary,omitempty"`
+
+	RoleID *string `json:"roleID,omitempty"`
+	// Contains information about the last time that an IAM role was used. This
+	// includes the date and time and the Region in which the role was last used.
+	// Activity is only reported for the trailing 400 days. This period can be shorter
+	// if your Region began supporting these features within the last year. The
+	// role might have been used more than 400 days ago. For more information, see
+	// Regions where data is tracked (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period)
+	// in the IAM User Guide.
+	//
+	// This data type is returned as a response element in the GetRole and GetAccountAuthorizationDetails
+	// operations.
+	RoleLastUsed *RoleLastUsed `json:"roleLastUsed,omitempty"`
+
+	RoleName *string `json:"roleName,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type RoleLastUsed struct {
+	LastUsedDate *metav1.Time `json:"lastUsedDate,omitempty"`
+
+	Region *string `json:"region,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type SAMLProviderListEntry struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	ValidUntil *metav1.Time `json:"validUntil,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type SSHPublicKey struct {
+	UploadDate *metav1.Time `json:"uploadDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type SSHPublicKeyMetadata struct {
+	UploadDate *metav1.Time `json:"uploadDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ServerCertificate struct {
+	Tags []*Tag `json:"tags,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ServerCertificateMetadata struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	Expiration *metav1.Time `json:"expiration,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+
+	ServerCertificateID *string `json:"serverCertificateID,omitempty"`
+
+	UploadDate *metav1.Time `json:"uploadDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ServiceLastAccessed struct {
+	LastAuthenticated *metav1.Time `json:"lastAuthenticated,omitempty"`
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	LastAuthenticatedEntity *string `json:"lastAuthenticatedEntity,omitempty"`
+
+	LastAuthenticatedRegion *string `json:"lastAuthenticatedRegion,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ServiceSpecificCredential struct {
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type ServiceSpecificCredentialMetadata struct {
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type SigningCertificate struct {
+	UploadDate *metav1.Time `json:"uploadDate,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type Tag struct {
+	Key *string `json:"key,omitempty"`
+
+	Value *string `json:"value,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type TrackedActionLastAccessed struct {
+	ActionName *string `json:"actionName,omitempty"`
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	LastAccessedEntity *string `json:"lastAccessedEntity,omitempty"`
+
+	LastAccessedRegion *string `json:"lastAccessedRegion,omitempty"`
+
+	LastAccessedTime *metav1.Time `json:"lastAccessedTime,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type User struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	PasswordLastUsed *metav1.Time `json:"passwordLastUsed,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+	// Contains information about an attached permissions boundary.
+	//
+	// An attached permissions boundary is a managed policy that has been attached
+	// to a user or role to set the permissions boundary.
+	//
+	// For more information about permissions boundaries, see Permissions boundaries
+	// for IAM identities (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
+	// in the IAM User Guide.
+	PermissionsBoundary *AttachedPermissionsBoundary `json:"permissionsBoundary,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+
+	UserID *string `json:"userID,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type UserDetail struct {
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	//
+	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+	// in the AWS General Reference.
+	ARN *string `json:"arn,omitempty"`
+
+	CreateDate *metav1.Time `json:"createDate,omitempty"`
+
+	Path *string `json:"path,omitempty"`
+	// Contains information about an attached permissions boundary.
+	//
+	// An attached permissions boundary is a managed policy that has been attached
+	// to a user or role to set the permissions boundary.
+	//
+	// For more information about permissions boundaries, see Permissions boundaries
+	// for IAM identities (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
+	// in the IAM User Guide.
+	PermissionsBoundary *AttachedPermissionsBoundary `json:"permissionsBoundary,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+
+	UserID *string `json:"userID,omitempty"`
+}
+
+// +kubebuilder:skipversion
+type VirtualMFADevice struct {
+	EnableDate *metav1.Time `json:"enableDate,omitempty"`
+
+	Tags []*Tag `json:"tags,omitempty"`
+}
diff --git a/examples/iam/instanceprofile.yaml b/examples/iam/instanceprofile.yaml
new file mode 100644
index 0000000000..7db2434e81
--- /dev/null
+++ b/examples/iam/instanceprofile.yaml
@@ -0,0 +1,13 @@
+---
+apiVersion: iam.aws.crossplane.io/v1alpha1
+kind: InstanceProfile
+metadata:
+  name: someinstanceprofile
+spec:
+  forProvider:
+    roleSelector:
+      matchLabels:
+        addToInstanceProfile: "true"
+    tags:
+      - key: k1
+        value: v1
diff --git a/examples/iam/roleforinstanceprofile.yaml b/examples/iam/roleforinstanceprofile.yaml
new file mode 100644
index 0000000000..dbd7e89e18
--- /dev/null
+++ b/examples/iam/roleforinstanceprofile.yaml
@@ -0,0 +1,33 @@
+---
+apiVersion: iam.aws.crossplane.io/v1beta1
+kind: Role
+metadata:
+  name: somerole
+  labels:
+    addToInstanceProfile: "true"
+spec:
+  forProvider:
+    assumeRolePolicyDocument: |
+      {
+        "Version": "2012-10-17",
+        "Statement": [
+            {
+                "Effect": "Allow",
+                "Principal": {
+                    "Service": [
+                        "ec2.amazonaws.com",
+                        "eks.amazonaws.com",
+                        "eks-fargate-pods.amazonaws.com",
+                        "lambda.amazonaws.com",
+                        "s3.amazonaws.com"
+                    ]
+                },
+                "Action": [
+                    "sts:AssumeRole"
+                ]
+            }
+        ]
+      }
+    tags:
+      - key: k1
+        value: v1
diff --git a/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml b/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml
new file mode 100644
index 0000000000..6906a92474
--- /dev/null
+++ b/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml
@@ -0,0 +1,312 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.6.2
+  creationTimestamp: null
+  name: instanceprofiles.iam.aws.crossplane.io
+spec:
+  group: iam.aws.crossplane.io
+  names:
+    categories:
+    - crossplane
+    - managed
+    - aws
+    kind: InstanceProfile
+    listKind: InstanceProfileList
+    plural: instanceprofiles
+    singular: instanceprofile
+  scope: Cluster
+  versions:
+  - additionalPrinterColumns:
+    - jsonPath: .status.conditions[?(@.type=='Ready')].status
+      name: READY
+      type: string
+    - jsonPath: .status.conditions[?(@.type=='Synced')].status
+      name: SYNCED
+      type: string
+    - jsonPath: .metadata.annotations.crossplane\.io/external-name
+      name: EXTERNAL-NAME
+      type: string
+    name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        description: InstanceProfile is the Schema for the InstanceProfiles API
+        properties:
+          apiVersion:
+            description: 'APIVersion defines the versioned schema of this representation
+              of an object. Servers should convert recognized schemas to the latest
+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+            type: string
+          kind:
+            description: 'Kind is a string value representing the REST resource this
+              object represents. Servers may infer this from the endpoint the client
+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: InstanceProfileSpec defines the desired state of InstanceProfile
+            properties:
+              deletionPolicy:
+                default: Delete
+                description: DeletionPolicy specifies what will happen to the underlying
+                  external when this managed resource is deleted - either "Delete"
+                  or "Orphan" the external resource.
+                enum:
+                - Orphan
+                - Delete
+                type: string
+              forProvider:
+                description: InstanceProfileParameters defines the desired state of
+                  InstanceProfile
+                properties:
+                  path:
+                    description: "The path to the instance profile. For more information
+                      about paths, see IAM Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html)
+                      in the IAM User Guide. \n This parameter is optional. If it
+                      is not included, it defaults to a slash (/). \n This parameter
+                      allows (through its regex pattern (http://wikipedia.org/wiki/regex))
+                      a string of characters consisting of either a forward slash
+                      (/) by itself or a string that must begin and end with forward
+                      slashes. In addition, it can contain any ASCII character from
+                      the ! (\\u0021) through the DEL character (\\u007F), including
+                      most punctuation characters, digits, and upper and lowercased
+                      letters."
+                    type: string
+                  role:
+                    description: Role is the ID for the Role to add to Instance Profile.
+                    type: string
+                  roleRef:
+                    description: RoleRef is a reference to an Role
+                    properties:
+                      name:
+                        description: Name of the referenced object.
+                        type: string
+                    required:
+                    - name
+                    type: object
+                  roleSelector:
+                    description: RoleSelector selects references to Role
+                    properties:
+                      matchControllerRef:
+                        description: MatchControllerRef ensures an object with the
+                          same controller reference as the selecting object is selected.
+                        type: boolean
+                      matchLabels:
+                        additionalProperties:
+                          type: string
+                        description: MatchLabels ensures an object with matching labels
+                          is selected.
+                        type: object
+                    type: object
+                  tags:
+                    description: "A list of tags that you want to attach to the newly
+                      created IAM instance profile. Each tag consists of a key name
+                      and an associated value. For more information about tagging,
+                      see Tagging IAM resources (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html)
+                      in the IAM User Guide. \n If any one of the tags is invalid
+                      or if you exceed the allowed maximum number of tags, then the
+                      entire request fails and the resource is not created."
+                    items:
+                      properties:
+                        key:
+                          type: string
+                        value:
+                          type: string
+                      type: object
+                    type: array
+                type: object
+              providerConfigRef:
+                default:
+                  name: default
+                description: ProviderConfigReference specifies how the provider that
+                  will be used to create, observe, update, and delete this managed
+                  resource should be configured.
+                properties:
+                  name:
+                    description: Name of the referenced object.
+                    type: string
+                required:
+                - name
+                type: object
+              providerRef:
+                description: 'ProviderReference specifies the provider that will be
+                  used to create, observe, update, and delete this managed resource.
+                  Deprecated: Please use ProviderConfigReference, i.e. `providerConfigRef`'
+                properties:
+                  name:
+                    description: Name of the referenced object.
+                    type: string
+                required:
+                - name
+                type: object
+              writeConnectionSecretToRef:
+                description: WriteConnectionSecretToReference specifies the namespace
+                  and name of a Secret to which any connection details for this managed
+                  resource should be written. Connection details frequently include
+                  the endpoint, username, and password required to connect to the
+                  managed resource.
+                properties:
+                  name:
+                    description: Name of the secret.
+                    type: string
+                  namespace:
+                    description: Namespace of the secret.
+                    type: string
+                required:
+                - name
+                - namespace
+                type: object
+            required:
+            - forProvider
+            type: object
+          status:
+            description: InstanceProfileStatus defines the observed state of InstanceProfile.
+            properties:
+              atProvider:
+                description: InstanceProfileObservation defines the observed state
+                  of InstanceProfile
+                properties:
+                  arn:
+                    description: The Amazon Resource Name (ARN) specifying the instance
+                      profile. For more information about ARNs and how to use them
+                      in policies, see IAM identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html)
+                      in the IAM User Guide.
+                    type: string
+                  createDate:
+                    description: The date when the instance profile was created.
+                    format: date-time
+                    type: string
+                  instanceProfileID:
+                    description: The stable and unique string identifying the instance
+                      profile. For more information about IDs, see IAM identifiers
+                      (https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html)
+                      in the IAM User Guide.
+                    type: string
+                  instanceProfileName:
+                    description: The name identifying the instance profile.
+                    type: string
+                  roles:
+                    description: The role associated with the instance profile.
+                    items:
+                      properties:
+                        arn:
+                          description: "The Amazon Resource Name (ARN). ARNs are unique
+                            identifiers for AWS resources. \n For more information
+                            about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+                            in the AWS General Reference."
+                          type: string
+                        assumeRolePolicyDocument:
+                          type: string
+                        createDate:
+                          format: date-time
+                          type: string
+                        description:
+                          type: string
+                        maxSessionDuration:
+                          format: int64
+                          type: integer
+                        path:
+                          type: string
+                        permissionsBoundary:
+                          description: "Contains information about an attached permissions
+                            boundary. \n An attached permissions boundary is a managed
+                            policy that has been attached to a user or role to set
+                            the permissions boundary. \n For more information about
+                            permissions boundaries, see Permissions boundaries for
+                            IAM identities (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html)
+                            in the IAM User Guide."
+                          properties:
+                            permissionsBoundaryARN:
+                              description: "The Amazon Resource Name (ARN). ARNs are
+                                unique identifiers for AWS resources. \n For more
+                                information about ARNs, go to Amazon Resource Names
+                                (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+                                in the AWS General Reference."
+                              type: string
+                            permissionsBoundaryType:
+                              type: string
+                          type: object
+                        roleID:
+                          type: string
+                        roleLastUsed:
+                          description: "Contains information about the last time that
+                            an IAM role was used. This includes the date and time
+                            and the Region in which the role was last used. Activity
+                            is only reported for the trailing 400 days. This period
+                            can be shorter if your Region began supporting these features
+                            within the last year. The role might have been used more
+                            than 400 days ago. For more information, see Regions where
+                            data is tracked (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html#access-advisor_tracking-period)
+                            in the IAM User Guide. \n This data type is returned as
+                            a response element in the GetRole and GetAccountAuthorizationDetails
+                            operations."
+                          properties:
+                            lastUsedDate:
+                              format: date-time
+                              type: string
+                            region:
+                              type: string
+                          type: object
+                        roleName:
+                          type: string
+                        tags:
+                          items:
+                            properties:
+                              key:
+                                type: string
+                              value:
+                                type: string
+                            type: object
+                          type: array
+                      type: object
+                    type: array
+                type: object
+              conditions:
+                description: Conditions of the resource.
+                items:
+                  description: A Condition that may apply to a resource.
+                  properties:
+                    lastTransitionTime:
+                      description: LastTransitionTime is the last time this condition
+                        transitioned from one status to another.
+                      format: date-time
+                      type: string
+                    message:
+                      description: A Message containing details about this condition's
+                        last transition from one status to another, if any.
+                      type: string
+                    reason:
+                      description: A Reason for this condition's last transition from
+                        one status to another.
+                      type: string
+                    status:
+                      description: Status of this condition; is it currently True,
+                        False, or Unknown?
+                      type: string
+                    type:
+                      description: Type of this condition. At most one of each condition
+                        type may apply to a resource at any point in time.
+                      type: string
+                  required:
+                  - lastTransitionTime
+                  - reason
+                  - status
+                  - type
+                  type: object
+                type: array
+            type: object
+        required:
+        - spec
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+status:
+  acceptedNames:
+    kind: ""
+    plural: ""
+  conditions: []
+  storedVersions: []
diff --git a/pkg/controller/aws.go b/pkg/controller/aws.go
index aebea71755..826b060b6c 100644
--- a/pkg/controller/aws.go
+++ b/pkg/controller/aws.go
@@ -101,6 +101,7 @@ import (
 	"github.com/crossplane/provider-aws/pkg/controller/iam/accesskey"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/group"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/grouppolicyattachment"
+	"github.com/crossplane/provider-aws/pkg/controller/iam/instanceprofile"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/groupusermembership"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/openidconnectprovider"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/policy"
@@ -164,6 +165,7 @@ func Setup(mgr ctrl.Manager, l logging.Logger, rl workqueue.RateLimiter, poll ti
 		eks.SetupCluster,
 		eksaddon.SetupAddon,
 		identityproviderconfig.SetupIdentityProviderConfig,
+		instanceprofile.SetupInstanceProfile,
 		elb.SetupELB,
 		elbattachment.SetupELBAttachment,
 		nodegroup.SetupNodeGroup,
diff --git a/pkg/controller/iam/instanceprofile/setup.go b/pkg/controller/iam/instanceprofile/setup.go
new file mode 100644
index 0000000000..134fac8472
--- /dev/null
+++ b/pkg/controller/iam/instanceprofile/setup.go
@@ -0,0 +1,110 @@
+/*
+Copyright 2020 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package instanceprofile
+
+import (
+	"context"
+	"time"
+
+	"github.com/aws/aws-sdk-go/aws/session"
+	"github.com/aws/aws-sdk-go/service/iam"
+	svcsdk "github.com/aws/aws-sdk-go/service/iam"
+	"k8s.io/client-go/util/workqueue"
+	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/controller"
+
+	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
+	"github.com/crossplane/crossplane-runtime/pkg/event"
+	"github.com/crossplane/crossplane-runtime/pkg/logging"
+	"github.com/crossplane/crossplane-runtime/pkg/meta"
+	"github.com/crossplane/crossplane-runtime/pkg/ratelimiter"
+	"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
+	"github.com/crossplane/crossplane-runtime/pkg/resource"
+
+	svcapitypes "github.com/crossplane/provider-aws/apis/iam/v1alpha1"
+	aws "github.com/crossplane/provider-aws/pkg/clients"
+)
+
+// SetupInstanceProfile adds a controller that reconciles InstanceProfile.
+func SetupInstanceProfile(mgr ctrl.Manager, l logging.Logger, rl workqueue.RateLimiter, poll time.Duration) error {
+	name := managed.ControllerName(svcapitypes.InstanceProfileGroupKind)
+	opts := []option{
+		func(e *external) {
+			e.preObserve = preObserve
+			e.postObserve = postObserve
+			e.preCreate = preCreate
+			e.postCreate = postCreate
+			e.preDelete = preDelete
+		},
+	}
+	return ctrl.NewControllerManagedBy(mgr).
+		Named(name).
+		WithOptions(controller.Options{
+			RateLimiter: ratelimiter.NewController(rl),
+		}).
+		For(&svcapitypes.InstanceProfile{}).
+		Complete(managed.NewReconciler(mgr,
+			resource.ManagedKind(svcapitypes.InstanceProfileGroupVersionKind),
+			managed.WithExternalConnecter(&connector{kube: mgr.GetClient(), opts: opts}),
+			managed.WithPollInterval(poll),
+			managed.WithLogger(l.WithValues("controller", name)),
+			managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name)))))
+}
+
+func preObserve(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.GetInstanceProfileInput) error {
+	obj.InstanceProfileName = aws.String(meta.GetExternalName(cr))
+	return nil
+}
+
+func postObserve(_ context.Context, cr *svcapitypes.InstanceProfile, _ *svcsdk.GetInstanceProfileOutput, obs managed.ExternalObservation, err error) (managed.ExternalObservation, error) {
+	if err != nil {
+		return managed.ExternalObservation{}, err
+	}
+	cr.SetConditions(xpv1.Available())
+	return obs, nil
+}
+
+func preCreate(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.CreateInstanceProfileInput) error {
+	obj.InstanceProfileName = aws.String(meta.GetExternalName(cr))
+	return nil
+}
+
+func postCreate(_ context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk.CreateInstanceProfileOutput, cre managed.ExternalCreation, err error) (managed.ExternalCreation, error) {
+	if err != nil {
+		return managed.ExternalCreation{}, err
+	}
+	svc := iam.New(session.New())
+	input := &iam.AddRoleToInstanceProfileInput{
+		InstanceProfileName: aws.String(cr.Name),
+		RoleName:            cr.Spec.ForProvider.Role,
+	}
+
+	_, err = svc.AddRoleToInstanceProfile(input)
+	return cre, err
+}
+
+func preDelete(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.DeleteInstanceProfileInput) (bool, error) {
+	obj.InstanceProfileName = aws.String(meta.GetExternalName(cr))
+	svc := iam.New(session.New())
+	input := &iam.RemoveRoleFromInstanceProfileInput{
+		InstanceProfileName: aws.String(cr.Name),
+		RoleName:            cr.Spec.ForProvider.Role,
+	}
+
+	_, err := svc.RemoveRoleFromInstanceProfile(input)
+	return false, err
+}
diff --git a/pkg/controller/iam/instanceprofile/zz_controller.go b/pkg/controller/iam/instanceprofile/zz_controller.go
new file mode 100644
index 0000000000..a49c3c8425
--- /dev/null
+++ b/pkg/controller/iam/instanceprofile/zz_controller.go
@@ -0,0 +1,314 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+package instanceprofile
+
+import (
+	"context"
+
+	svcapi "github.com/aws/aws-sdk-go/service/iam"
+	svcsdk "github.com/aws/aws-sdk-go/service/iam"
+	svcsdkapi "github.com/aws/aws-sdk-go/service/iam/iamiface"
+	"github.com/google/go-cmp/cmp"
+	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
+	"github.com/crossplane/crossplane-runtime/pkg/meta"
+	"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
+	cpresource "github.com/crossplane/crossplane-runtime/pkg/resource"
+
+	svcapitypes "github.com/crossplane/provider-aws/apis/iam/v1alpha1"
+	awsclient "github.com/crossplane/provider-aws/pkg/clients"
+)
+
+const (
+	errUnexpectedObject = "managed resource is not an InstanceProfile resource"
+
+	errCreateSession = "cannot create a new session"
+	errCreate        = "cannot create InstanceProfile in AWS"
+	errUpdate        = "cannot update InstanceProfile in AWS"
+	errDescribe      = "failed to describe InstanceProfile"
+	errDelete        = "failed to delete InstanceProfile"
+)
+
+type connector struct {
+	kube client.Client
+	opts []option
+}
+
+func (c *connector) Connect(ctx context.Context, mg cpresource.Managed) (managed.ExternalClient, error) {
+	sess, err := awsclient.GetConfigV1(ctx, c.kube, mg, awsclient.GlobalRegion)
+	if err != nil {
+		return nil, errors.Wrap(err, errCreateSession)
+	}
+	return newExternal(c.kube, svcapi.New(sess), c.opts), nil
+}
+
+func (e *external) Observe(ctx context.Context, mg cpresource.Managed) (managed.ExternalObservation, error) {
+	cr, ok := mg.(*svcapitypes.InstanceProfile)
+	if !ok {
+		return managed.ExternalObservation{}, errors.New(errUnexpectedObject)
+	}
+	if meta.GetExternalName(cr) == "" {
+		return managed.ExternalObservation{
+			ResourceExists: false,
+		}, nil
+	}
+	input := GenerateGetInstanceProfileInput(cr)
+	if err := e.preObserve(ctx, cr, input); err != nil {
+		return managed.ExternalObservation{}, errors.Wrap(err, "pre-observe failed")
+	}
+	resp, err := e.client.GetInstanceProfileWithContext(ctx, input)
+	if err != nil {
+		return managed.ExternalObservation{ResourceExists: false}, awsclient.Wrap(cpresource.Ignore(IsNotFound, err), errDescribe)
+	}
+	currentSpec := cr.Spec.ForProvider.DeepCopy()
+	if err := e.lateInitialize(&cr.Spec.ForProvider, resp); err != nil {
+		return managed.ExternalObservation{}, errors.Wrap(err, "late-init failed")
+	}
+	GenerateInstanceProfile(resp).Status.AtProvider.DeepCopyInto(&cr.Status.AtProvider)
+
+	upToDate, err := e.isUpToDate(cr, resp)
+	if err != nil {
+		return managed.ExternalObservation{}, errors.Wrap(err, "isUpToDate check failed")
+	}
+	return e.postObserve(ctx, cr, resp, managed.ExternalObservation{
+		ResourceExists:          true,
+		ResourceUpToDate:        upToDate,
+		ResourceLateInitialized: !cmp.Equal(&cr.Spec.ForProvider, currentSpec),
+	}, nil)
+}
+
+func (e *external) Create(ctx context.Context, mg cpresource.Managed) (managed.ExternalCreation, error) {
+	cr, ok := mg.(*svcapitypes.InstanceProfile)
+	if !ok {
+		return managed.ExternalCreation{}, errors.New(errUnexpectedObject)
+	}
+	cr.Status.SetConditions(xpv1.Creating())
+	input := GenerateCreateInstanceProfileInput(cr)
+	if err := e.preCreate(ctx, cr, input); err != nil {
+		return managed.ExternalCreation{}, errors.Wrap(err, "pre-create failed")
+	}
+	resp, err := e.client.CreateInstanceProfileWithContext(ctx, input)
+	if err != nil {
+		return managed.ExternalCreation{}, awsclient.Wrap(err, errCreate)
+	}
+
+	if resp.InstanceProfile.Arn != nil {
+		cr.Status.AtProvider.ARN = resp.InstanceProfile.Arn
+	} else {
+		cr.Status.AtProvider.ARN = nil
+	}
+	if resp.InstanceProfile.CreateDate != nil {
+		cr.Status.AtProvider.CreateDate = &metav1.Time{*resp.InstanceProfile.CreateDate}
+	} else {
+		cr.Status.AtProvider.CreateDate = nil
+	}
+	if resp.InstanceProfile.InstanceProfileId != nil {
+		cr.Status.AtProvider.InstanceProfileID = resp.InstanceProfile.InstanceProfileId
+	} else {
+		cr.Status.AtProvider.InstanceProfileID = nil
+	}
+	if resp.InstanceProfile.InstanceProfileName != nil {
+		cr.Status.AtProvider.InstanceProfileName = resp.InstanceProfile.InstanceProfileName
+	} else {
+		cr.Status.AtProvider.InstanceProfileName = nil
+	}
+	if resp.InstanceProfile.Path != nil {
+		cr.Spec.ForProvider.Path = resp.InstanceProfile.Path
+	} else {
+		cr.Spec.ForProvider.Path = nil
+	}
+	if resp.InstanceProfile.Roles != nil {
+		f5 := []*svcapitypes.Role{}
+		for _, f5iter := range resp.InstanceProfile.Roles {
+			f5elem := &svcapitypes.Role{}
+			if f5iter.Arn != nil {
+				f5elem.ARN = f5iter.Arn
+			}
+			if f5iter.AssumeRolePolicyDocument != nil {
+				f5elem.AssumeRolePolicyDocument = f5iter.AssumeRolePolicyDocument
+			}
+			if f5iter.CreateDate != nil {
+				f5elem.CreateDate = &metav1.Time{*f5iter.CreateDate}
+			}
+			if f5iter.Description != nil {
+				f5elem.Description = f5iter.Description
+			}
+			if f5iter.MaxSessionDuration != nil {
+				f5elem.MaxSessionDuration = f5iter.MaxSessionDuration
+			}
+			if f5iter.Path != nil {
+				f5elem.Path = f5iter.Path
+			}
+			if f5iter.PermissionsBoundary != nil {
+				f5elemf6 := &svcapitypes.AttachedPermissionsBoundary{}
+				if f5iter.PermissionsBoundary.PermissionsBoundaryArn != nil {
+					f5elemf6.PermissionsBoundaryARN = f5iter.PermissionsBoundary.PermissionsBoundaryArn
+				}
+				if f5iter.PermissionsBoundary.PermissionsBoundaryType != nil {
+					f5elemf6.PermissionsBoundaryType = f5iter.PermissionsBoundary.PermissionsBoundaryType
+				}
+				f5elem.PermissionsBoundary = f5elemf6
+			}
+			if f5iter.RoleId != nil {
+				f5elem.RoleID = f5iter.RoleId
+			}
+			if f5iter.RoleLastUsed != nil {
+				f5elemf8 := &svcapitypes.RoleLastUsed{}
+				if f5iter.RoleLastUsed.LastUsedDate != nil {
+					f5elemf8.LastUsedDate = &metav1.Time{*f5iter.RoleLastUsed.LastUsedDate}
+				}
+				if f5iter.RoleLastUsed.Region != nil {
+					f5elemf8.Region = f5iter.RoleLastUsed.Region
+				}
+				f5elem.RoleLastUsed = f5elemf8
+			}
+			if f5iter.RoleName != nil {
+				f5elem.RoleName = f5iter.RoleName
+			}
+			if f5iter.Tags != nil {
+				f5elemf10 := []*svcapitypes.Tag{}
+				for _, f5elemf10iter := range f5iter.Tags {
+					f5elemf10elem := &svcapitypes.Tag{}
+					if f5elemf10iter.Key != nil {
+						f5elemf10elem.Key = f5elemf10iter.Key
+					}
+					if f5elemf10iter.Value != nil {
+						f5elemf10elem.Value = f5elemf10iter.Value
+					}
+					f5elemf10 = append(f5elemf10, f5elemf10elem)
+				}
+				f5elem.Tags = f5elemf10
+			}
+			f5 = append(f5, f5elem)
+		}
+		cr.Status.AtProvider.Roles = f5
+	} else {
+		cr.Status.AtProvider.Roles = nil
+	}
+	if resp.InstanceProfile.Tags != nil {
+		f6 := []*svcapitypes.Tag{}
+		for _, f6iter := range resp.InstanceProfile.Tags {
+			f6elem := &svcapitypes.Tag{}
+			if f6iter.Key != nil {
+				f6elem.Key = f6iter.Key
+			}
+			if f6iter.Value != nil {
+				f6elem.Value = f6iter.Value
+			}
+			f6 = append(f6, f6elem)
+		}
+		cr.Spec.ForProvider.Tags = f6
+	} else {
+		cr.Spec.ForProvider.Tags = nil
+	}
+
+	return e.postCreate(ctx, cr, resp, managed.ExternalCreation{}, err)
+}
+
+func (e *external) Update(ctx context.Context, mg cpresource.Managed) (managed.ExternalUpdate, error) {
+	return e.update(ctx, mg)
+
+}
+
+func (e *external) Delete(ctx context.Context, mg cpresource.Managed) error {
+	cr, ok := mg.(*svcapitypes.InstanceProfile)
+	if !ok {
+		return errors.New(errUnexpectedObject)
+	}
+	cr.Status.SetConditions(xpv1.Deleting())
+	input := GenerateDeleteInstanceProfileInput(cr)
+	ignore, err := e.preDelete(ctx, cr, input)
+	if err != nil {
+		return errors.Wrap(err, "pre-delete failed")
+	}
+	if ignore {
+		return nil
+	}
+	resp, err := e.client.DeleteInstanceProfileWithContext(ctx, input)
+	return e.postDelete(ctx, cr, resp, awsclient.Wrap(cpresource.Ignore(IsNotFound, err), errDelete))
+}
+
+type option func(*external)
+
+func newExternal(kube client.Client, client svcsdkapi.IAMAPI, opts []option) *external {
+	e := &external{
+		kube:           kube,
+		client:         client,
+		preObserve:     nopPreObserve,
+		postObserve:    nopPostObserve,
+		lateInitialize: nopLateInitialize,
+		isUpToDate:     alwaysUpToDate,
+		preCreate:      nopPreCreate,
+		postCreate:     nopPostCreate,
+		preDelete:      nopPreDelete,
+		postDelete:     nopPostDelete,
+		update:         nopUpdate,
+	}
+	for _, f := range opts {
+		f(e)
+	}
+	return e
+}
+
+type external struct {
+	kube           client.Client
+	client         svcsdkapi.IAMAPI
+	preObserve     func(context.Context, *svcapitypes.InstanceProfile, *svcsdk.GetInstanceProfileInput) error
+	postObserve    func(context.Context, *svcapitypes.InstanceProfile, *svcsdk.GetInstanceProfileOutput, managed.ExternalObservation, error) (managed.ExternalObservation, error)
+	lateInitialize func(*svcapitypes.InstanceProfileParameters, *svcsdk.GetInstanceProfileOutput) error
+	isUpToDate     func(*svcapitypes.InstanceProfile, *svcsdk.GetInstanceProfileOutput) (bool, error)
+	preCreate      func(context.Context, *svcapitypes.InstanceProfile, *svcsdk.CreateInstanceProfileInput) error
+	postCreate     func(context.Context, *svcapitypes.InstanceProfile, *svcsdk.CreateInstanceProfileOutput, managed.ExternalCreation, error) (managed.ExternalCreation, error)
+	preDelete      func(context.Context, *svcapitypes.InstanceProfile, *svcsdk.DeleteInstanceProfileInput) (bool, error)
+	postDelete     func(context.Context, *svcapitypes.InstanceProfile, *svcsdk.DeleteInstanceProfileOutput, error) error
+	update         func(context.Context, cpresource.Managed) (managed.ExternalUpdate, error)
+}
+
+func nopPreObserve(context.Context, *svcapitypes.InstanceProfile, *svcsdk.GetInstanceProfileInput) error {
+	return nil
+}
+
+func nopPostObserve(_ context.Context, _ *svcapitypes.InstanceProfile, _ *svcsdk.GetInstanceProfileOutput, obs managed.ExternalObservation, err error) (managed.ExternalObservation, error) {
+	return obs, err
+}
+func nopLateInitialize(*svcapitypes.InstanceProfileParameters, *svcsdk.GetInstanceProfileOutput) error {
+	return nil
+}
+func alwaysUpToDate(*svcapitypes.InstanceProfile, *svcsdk.GetInstanceProfileOutput) (bool, error) {
+	return true, nil
+}
+
+func nopPreCreate(context.Context, *svcapitypes.InstanceProfile, *svcsdk.CreateInstanceProfileInput) error {
+	return nil
+}
+func nopPostCreate(_ context.Context, _ *svcapitypes.InstanceProfile, _ *svcsdk.CreateInstanceProfileOutput, cre managed.ExternalCreation, err error) (managed.ExternalCreation, error) {
+	return cre, err
+}
+func nopPreDelete(context.Context, *svcapitypes.InstanceProfile, *svcsdk.DeleteInstanceProfileInput) (bool, error) {
+	return false, nil
+}
+func nopPostDelete(_ context.Context, _ *svcapitypes.InstanceProfile, _ *svcsdk.DeleteInstanceProfileOutput, err error) error {
+	return err
+}
+func nopUpdate(context.Context, cpresource.Managed) (managed.ExternalUpdate, error) {
+	return managed.ExternalUpdate{}, nil
+}
diff --git a/pkg/controller/iam/instanceprofile/zz_conversions.go b/pkg/controller/iam/instanceprofile/zz_conversions.go
new file mode 100644
index 0000000000..ef9cb8926e
--- /dev/null
+++ b/pkg/controller/iam/instanceprofile/zz_conversions.go
@@ -0,0 +1,197 @@
+/*
+Copyright 2021 The Crossplane Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by ack-generate. DO NOT EDIT.
+
+package instanceprofile
+
+import (
+	"github.com/aws/aws-sdk-go/aws/awserr"
+	svcsdk "github.com/aws/aws-sdk-go/service/iam"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	svcapitypes "github.com/crossplane/provider-aws/apis/iam/v1alpha1"
+)
+
+// NOTE(muvaf): We return pointers in case the function needs to start with an
+// empty object, hence need to return a new pointer.
+
+// GenerateGetInstanceProfileInput returns input for read
+// operation.
+func GenerateGetInstanceProfileInput(cr *svcapitypes.InstanceProfile) *svcsdk.GetInstanceProfileInput {
+	res := &svcsdk.GetInstanceProfileInput{}
+
+	if cr.Status.AtProvider.InstanceProfileName != nil {
+		res.SetInstanceProfileName(*cr.Status.AtProvider.InstanceProfileName)
+	}
+
+	return res
+}
+
+// GenerateInstanceProfile returns the current state in the form of *svcapitypes.InstanceProfile.
+func GenerateInstanceProfile(resp *svcsdk.GetInstanceProfileOutput) *svcapitypes.InstanceProfile {
+	cr := &svcapitypes.InstanceProfile{}
+
+	if resp.InstanceProfile.Arn != nil {
+		cr.Status.AtProvider.ARN = resp.InstanceProfile.Arn
+	} else {
+		cr.Status.AtProvider.ARN = nil
+	}
+	if resp.InstanceProfile.CreateDate != nil {
+		cr.Status.AtProvider.CreateDate = &metav1.Time{*resp.InstanceProfile.CreateDate}
+	} else {
+		cr.Status.AtProvider.CreateDate = nil
+	}
+	if resp.InstanceProfile.InstanceProfileId != nil {
+		cr.Status.AtProvider.InstanceProfileID = resp.InstanceProfile.InstanceProfileId
+	} else {
+		cr.Status.AtProvider.InstanceProfileID = nil
+	}
+	if resp.InstanceProfile.InstanceProfileName != nil {
+		cr.Status.AtProvider.InstanceProfileName = resp.InstanceProfile.InstanceProfileName
+	} else {
+		cr.Status.AtProvider.InstanceProfileName = nil
+	}
+	if resp.InstanceProfile.Path != nil {
+		cr.Spec.ForProvider.Path = resp.InstanceProfile.Path
+	} else {
+		cr.Spec.ForProvider.Path = nil
+	}
+	if resp.InstanceProfile.Roles != nil {
+		f5 := []*svcapitypes.Role{}
+		for _, f5iter := range resp.InstanceProfile.Roles {
+			f5elem := &svcapitypes.Role{}
+			if f5iter.Arn != nil {
+				f5elem.ARN = f5iter.Arn
+			}
+			if f5iter.AssumeRolePolicyDocument != nil {
+				f5elem.AssumeRolePolicyDocument = f5iter.AssumeRolePolicyDocument
+			}
+			if f5iter.CreateDate != nil {
+				f5elem.CreateDate = &metav1.Time{*f5iter.CreateDate}
+			}
+			if f5iter.Description != nil {
+				f5elem.Description = f5iter.Description
+			}
+			if f5iter.MaxSessionDuration != nil {
+				f5elem.MaxSessionDuration = f5iter.MaxSessionDuration
+			}
+			if f5iter.Path != nil {
+				f5elem.Path = f5iter.Path
+			}
+			if f5iter.PermissionsBoundary != nil {
+				f5elemf6 := &svcapitypes.AttachedPermissionsBoundary{}
+				if f5iter.PermissionsBoundary.PermissionsBoundaryArn != nil {
+					f5elemf6.PermissionsBoundaryARN = f5iter.PermissionsBoundary.PermissionsBoundaryArn
+				}
+				if f5iter.PermissionsBoundary.PermissionsBoundaryType != nil {
+					f5elemf6.PermissionsBoundaryType = f5iter.PermissionsBoundary.PermissionsBoundaryType
+				}
+				f5elem.PermissionsBoundary = f5elemf6
+			}
+			if f5iter.RoleId != nil {
+				f5elem.RoleID = f5iter.RoleId
+			}
+			if f5iter.RoleLastUsed != nil {
+				f5elemf8 := &svcapitypes.RoleLastUsed{}
+				if f5iter.RoleLastUsed.LastUsedDate != nil {
+					f5elemf8.LastUsedDate = &metav1.Time{*f5iter.RoleLastUsed.LastUsedDate}
+				}
+				if f5iter.RoleLastUsed.Region != nil {
+					f5elemf8.Region = f5iter.RoleLastUsed.Region
+				}
+				f5elem.RoleLastUsed = f5elemf8
+			}
+			if f5iter.RoleName != nil {
+				f5elem.RoleName = f5iter.RoleName
+			}
+			if f5iter.Tags != nil {
+				f5elemf10 := []*svcapitypes.Tag{}
+				for _, f5elemf10iter := range f5iter.Tags {
+					f5elemf10elem := &svcapitypes.Tag{}
+					if f5elemf10iter.Key != nil {
+						f5elemf10elem.Key = f5elemf10iter.Key
+					}
+					if f5elemf10iter.Value != nil {
+						f5elemf10elem.Value = f5elemf10iter.Value
+					}
+					f5elemf10 = append(f5elemf10, f5elemf10elem)
+				}
+				f5elem.Tags = f5elemf10
+			}
+			f5 = append(f5, f5elem)
+		}
+		cr.Status.AtProvider.Roles = f5
+	} else {
+		cr.Status.AtProvider.Roles = nil
+	}
+	if resp.InstanceProfile.Tags != nil {
+		f6 := []*svcapitypes.Tag{}
+		for _, f6iter := range resp.InstanceProfile.Tags {
+			f6elem := &svcapitypes.Tag{}
+			if f6iter.Key != nil {
+				f6elem.Key = f6iter.Key
+			}
+			if f6iter.Value != nil {
+				f6elem.Value = f6iter.Value
+			}
+			f6 = append(f6, f6elem)
+		}
+		cr.Spec.ForProvider.Tags = f6
+	} else {
+		cr.Spec.ForProvider.Tags = nil
+	}
+
+	return cr
+}
+
+// GenerateCreateInstanceProfileInput returns a create input.
+func GenerateCreateInstanceProfileInput(cr *svcapitypes.InstanceProfile) *svcsdk.CreateInstanceProfileInput {
+	res := &svcsdk.CreateInstanceProfileInput{}
+
+	if cr.Spec.ForProvider.Path != nil {
+		res.SetPath(*cr.Spec.ForProvider.Path)
+	}
+	if cr.Spec.ForProvider.Tags != nil {
+		f1 := []*svcsdk.Tag{}
+		for _, f1iter := range cr.Spec.ForProvider.Tags {
+			f1elem := &svcsdk.Tag{}
+			if f1iter.Key != nil {
+				f1elem.SetKey(*f1iter.Key)
+			}
+			if f1iter.Value != nil {
+				f1elem.SetValue(*f1iter.Value)
+			}
+			f1 = append(f1, f1elem)
+		}
+		res.SetTags(f1)
+	}
+
+	return res
+}
+
+// GenerateDeleteInstanceProfileInput returns a deletion input.
+func GenerateDeleteInstanceProfileInput(cr *svcapitypes.InstanceProfile) *svcsdk.DeleteInstanceProfileInput {
+	res := &svcsdk.DeleteInstanceProfileInput{}
+
+	return res
+}
+
+// IsNotFound returns whether the given error is of type NotFound or not.
+func IsNotFound(err error) bool {
+	awsErr, ok := err.(awserr.Error)
+	return ok && awsErr.Code() == "NoSuchEntity"
+}

From ef890f744d89ca4a3b1419eec47f4d54c3b64385 Mon Sep 17 00:00:00 2001
From: Yury Tsarev <yury@upbound.io>
Date: Fri, 18 Feb 2022 19:03:04 +0100
Subject: [PATCH 2/4] Fix linting

Signed-off-by: Yury Tsarev <yury@upbound.io>
---
 Makefile                                    | 2 +-
 pkg/controller/iam/instanceprofile/setup.go | 8 +++++---
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 1d36ec0185..4d8f37a968 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ PLATFORMS ?= linux_amd64 linux_arm64
 
 CODE_GENERATOR_REPO ?= https://github.com/aws-controllers-k8s/code-generator.git
 CODE_GENERATOR_COMMIT ?= f8c0f4711a91e50335450521e3c49673d135d56d
-GENERATED_SERVICES := $(shell find ./apis/ -type f -name generator-config.yaml | cut -d/ -f 3 | tr '\n' ' ')
+GENERATED_SERVICES := $(shell find ./apis -type f -name generator-config.yaml | cut -d/ -f 3 | tr '\n' ' ')
 
 # kind-related versions
 KIND_VERSION ?= v0.11.1
diff --git a/pkg/controller/iam/instanceprofile/setup.go b/pkg/controller/iam/instanceprofile/setup.go
index 134fac8472..c38d251722 100644
--- a/pkg/controller/iam/instanceprofile/setup.go
+++ b/pkg/controller/iam/instanceprofile/setup.go
@@ -87,7 +87,8 @@ func postCreate(_ context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk
 	if err != nil {
 		return managed.ExternalCreation{}, err
 	}
-	svc := iam.New(session.New())
+	sess, err := session.NewSession()
+	svc := iam.New(sess)
 	input := &iam.AddRoleToInstanceProfileInput{
 		InstanceProfileName: aws.String(cr.Name),
 		RoleName:            cr.Spec.ForProvider.Role,
@@ -99,12 +100,13 @@ func postCreate(_ context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk
 
 func preDelete(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.DeleteInstanceProfileInput) (bool, error) {
 	obj.InstanceProfileName = aws.String(meta.GetExternalName(cr))
-	svc := iam.New(session.New())
+	sess, err := session.NewSession()
+	svc := iam.New(sess)
 	input := &iam.RemoveRoleFromInstanceProfileInput{
 		InstanceProfileName: aws.String(cr.Name),
 		RoleName:            cr.Spec.ForProvider.Role,
 	}
 
-	_, err := svc.RemoveRoleFromInstanceProfile(input)
+	_, err = svc.RemoveRoleFromInstanceProfile(input)
 	return false, err
 }

From f5e5a2a5514865a6ac0bcf61b52dd878f30cf4e4 Mon Sep 17 00:00:00 2001
From: Yury Tsarev <yury@upbound.io>
Date: Sun, 20 Feb 2022 22:03:11 +0100
Subject: [PATCH 3/4] Rebase with #1122, make reviewable green

Signed-off-by: Yury Tsarev <yury@upbound.io>
---
 apis/iam/v1alpha1/zz_types.go                 | 90 +++++++++++--------
 ...am.aws.crossplane.io_instanceprofiles.yaml | 15 ++--
 pkg/controller/aws.go                         |  2 +-
 pkg/controller/iam/instanceprofile/setup.go   |  6 ++
 4 files changed, 69 insertions(+), 44 deletions(-)

diff --git a/apis/iam/v1alpha1/zz_types.go b/apis/iam/v1alpha1/zz_types.go
index e6bb8e3793..4fa826a7fa 100644
--- a/apis/iam/v1alpha1/zz_types.go
+++ b/apis/iam/v1alpha1/zz_types.go
@@ -55,10 +55,11 @@ type AccessKeyMetadata struct {
 
 // +kubebuilder:skipversion
 type AttachedPermissionsBoundary struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	PermissionsBoundaryARN *string `json:"permissionsBoundaryARN,omitempty"`
 
 	PermissionsBoundaryType *string `json:"permissionsBoundaryType,omitempty"`
@@ -66,10 +67,11 @@ type AttachedPermissionsBoundary struct {
 
 // +kubebuilder:skipversion
 type AttachedPolicy struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	PolicyARN *string `json:"policyARN,omitempty"`
 }
 
@@ -80,10 +82,11 @@ type EntityDetails struct {
 
 // +kubebuilder:skipversion
 type EntityInfo struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	ID *string `json:"id,omitempty"`
@@ -100,10 +103,11 @@ type ErrorDetails struct {
 
 // +kubebuilder:skipversion
 type Group struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -115,10 +119,11 @@ type Group struct {
 
 // +kubebuilder:skipversion
 type GroupDetail struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -130,10 +135,11 @@ type GroupDetail struct {
 
 // +kubebuilder:skipversion
 type InstanceProfile_SDK struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -165,10 +171,11 @@ type MFADevice struct {
 
 // +kubebuilder:skipversion
 type ManagedPolicyDetail struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -182,10 +189,11 @@ type ManagedPolicyDetail struct {
 
 // +kubebuilder:skipversion
 type OpenIDConnectProviderListEntry struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 }
 
@@ -216,10 +224,11 @@ type PermissionsBoundaryDecisionDetail struct {
 
 // +kubebuilder:skipversion
 type Policy struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -240,10 +249,11 @@ type PolicyDetail struct {
 
 // +kubebuilder:skipversion
 type PolicyGrantingServiceAccess struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	PolicyARN *string `json:"policyARN,omitempty"`
 }
 
@@ -275,10 +285,11 @@ type PolicyVersion struct {
 
 // +kubebuilder:skipversion
 type Role struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	AssumeRolePolicyDocument *string `json:"assumeRolePolicyDocument,omitempty"`
@@ -320,10 +331,11 @@ type Role struct {
 
 // +kubebuilder:skipversion
 type RoleDetail struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	AssumeRolePolicyDocument *string `json:"assumeRolePolicyDocument,omitempty"`
@@ -370,10 +382,11 @@ type RoleLastUsed struct {
 
 // +kubebuilder:skipversion
 type SAMLProviderListEntry struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -398,10 +411,11 @@ type ServerCertificate struct {
 
 // +kubebuilder:skipversion
 type ServerCertificateMetadata struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	Expiration *metav1.Time `json:"expiration,omitempty"`
@@ -416,10 +430,11 @@ type ServerCertificateMetadata struct {
 // +kubebuilder:skipversion
 type ServiceLastAccessed struct {
 	LastAuthenticated *metav1.Time `json:"lastAuthenticated,omitempty"`
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	LastAuthenticatedEntity *string `json:"lastAuthenticatedEntity,omitempty"`
 
 	LastAuthenticatedRegion *string `json:"lastAuthenticatedRegion,omitempty"`
@@ -450,10 +465,11 @@ type Tag struct {
 // +kubebuilder:skipversion
 type TrackedActionLastAccessed struct {
 	ActionName *string `json:"actionName,omitempty"`
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	LastAccessedEntity *string `json:"lastAccessedEntity,omitempty"`
 
 	LastAccessedRegion *string `json:"lastAccessedRegion,omitempty"`
@@ -463,10 +479,11 @@ type TrackedActionLastAccessed struct {
 
 // +kubebuilder:skipversion
 type User struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
@@ -491,10 +508,11 @@ type User struct {
 
 // +kubebuilder:skipversion
 type UserDetail struct {
-	// The Amazon Resource Name (ARN). ARNs are unique identifiers for AWS resources.
+	// The Amazon Resource Name (ARN). ARNs are unique identifiers for Amazon Web
+	// Services resources.
 	//
 	// For more information about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-	// in the AWS General Reference.
+	// in the Amazon Web Services General Reference.
 	ARN *string `json:"arn,omitempty"`
 
 	CreateDate *metav1.Time `json:"createDate,omitempty"`
diff --git a/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml b/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml
index 6906a92474..938fab6f0b 100644
--- a/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml
+++ b/package/crds/iam.aws.crossplane.io_instanceprofiles.yaml
@@ -193,9 +193,10 @@ spec:
                       properties:
                         arn:
                           description: "The Amazon Resource Name (ARN). ARNs are unique
-                            identifiers for AWS resources. \n For more information
-                            about ARNs, go to Amazon Resource Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-                            in the AWS General Reference."
+                            identifiers for Amazon Web Services resources. \n For
+                            more information about ARNs, go to Amazon Resource Names
+                            (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+                            in the Amazon Web Services General Reference."
                           type: string
                         assumeRolePolicyDocument:
                           type: string
@@ -220,10 +221,10 @@ spec:
                           properties:
                             permissionsBoundaryARN:
                               description: "The Amazon Resource Name (ARN). ARNs are
-                                unique identifiers for AWS resources. \n For more
-                                information about ARNs, go to Amazon Resource Names
-                                (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
-                                in the AWS General Reference."
+                                unique identifiers for Amazon Web Services resources.
+                                \n For more information about ARNs, go to Amazon Resource
+                                Names (ARNs) (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
+                                in the Amazon Web Services General Reference."
                               type: string
                             permissionsBoundaryType:
                               type: string
diff --git a/pkg/controller/aws.go b/pkg/controller/aws.go
index 826b060b6c..86def33061 100644
--- a/pkg/controller/aws.go
+++ b/pkg/controller/aws.go
@@ -101,8 +101,8 @@ import (
 	"github.com/crossplane/provider-aws/pkg/controller/iam/accesskey"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/group"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/grouppolicyattachment"
-	"github.com/crossplane/provider-aws/pkg/controller/iam/instanceprofile"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/groupusermembership"
+	"github.com/crossplane/provider-aws/pkg/controller/iam/instanceprofile"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/openidconnectprovider"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/policy"
 	"github.com/crossplane/provider-aws/pkg/controller/iam/role"
diff --git a/pkg/controller/iam/instanceprofile/setup.go b/pkg/controller/iam/instanceprofile/setup.go
index c38d251722..629091a260 100644
--- a/pkg/controller/iam/instanceprofile/setup.go
+++ b/pkg/controller/iam/instanceprofile/setup.go
@@ -88,6 +88,9 @@ func postCreate(_ context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk
 		return managed.ExternalCreation{}, err
 	}
 	sess, err := session.NewSession()
+	if err != nil {
+		return cre, err
+	}
 	svc := iam.New(sess)
 	input := &iam.AddRoleToInstanceProfileInput{
 		InstanceProfileName: aws.String(cr.Name),
@@ -101,6 +104,9 @@ func postCreate(_ context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk
 func preDelete(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.DeleteInstanceProfileInput) (bool, error) {
 	obj.InstanceProfileName = aws.String(meta.GetExternalName(cr))
 	sess, err := session.NewSession()
+	if err != nil {
+		return false, err
+	}
 	svc := iam.New(sess)
 	input := &iam.RemoveRoleFromInstanceProfileInput{
 		InstanceProfileName: aws.String(cr.Name),

From 24c367eb84b33df334f66bb2be5bccfcd4c7d964 Mon Sep 17 00:00:00 2001
From: Yury Tsarev <yury@upbound.io>
Date: Tue, 8 Mar 2022 11:27:29 +0100
Subject: [PATCH 4/4] Apply suggestions from code review

Co-authored-by: Christopher Haar <chhaar30@googlemail.com>
Signed-off-by: Yury Tsarev <yury@upbound.io>
---
 pkg/controller/iam/instanceprofile/setup.go | 34 +++++++++------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/pkg/controller/iam/instanceprofile/setup.go b/pkg/controller/iam/instanceprofile/setup.go
index 629091a260..c6c056a7c8 100644
--- a/pkg/controller/iam/instanceprofile/setup.go
+++ b/pkg/controller/iam/instanceprofile/setup.go
@@ -21,8 +21,8 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/iam"
 	svcsdk "github.com/aws/aws-sdk-go/service/iam"
+	svcsdkapi "github.com/aws/aws-sdk-go/service/iam/iamiface"
 	"k8s.io/client-go/util/workqueue"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -44,6 +44,7 @@ func SetupInstanceProfile(mgr ctrl.Manager, l logging.Logger, rl workqueue.RateL
 	name := managed.ControllerName(svcapitypes.InstanceProfileGroupKind)
 	opts := []option{
 		func(e *external) {
+			u := &updater{client: e.client}
 			e.preObserve = preObserve
 			e.postObserve = postObserve
 			e.preCreate = preCreate
@@ -83,36 +84,31 @@ func preCreate(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.C
 	return nil
 }
 
-func postCreate(_ context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk.CreateInstanceProfileOutput, cre managed.ExternalCreation, err error) (managed.ExternalCreation, error) {
+type updater struct {
+	client svcsdkapi.IAMAPI
+}
+
+func (u *updater) postCreate(ctx context.Context, cr *svcapitypes.InstanceProfile, resp *svcsdk.CreateInstanceProfileOutput, cre managed.ExternalCreation, err error) (managed.ExternalCreation, error) {
 	if err != nil {
 		return managed.ExternalCreation{}, err
 	}
-	sess, err := session.NewSession()
-	if err != nil {
-		return cre, err
-	}
-	svc := iam.New(sess)
-	input := &iam.AddRoleToInstanceProfileInput{
-		InstanceProfileName: aws.String(cr.Name),
+
+	input := &svcsdk.AddRoleToInstanceProfileInput{
+		InstanceProfileName: aws.String(meta.GetExternalName(cr)),
 		RoleName:            cr.Spec.ForProvider.Role,
 	}
 
-	_, err = svc.AddRoleToInstanceProfile(input)
+	_, err = u.client.AddRoleToInstanceProfileWithContext(ctx, input)
 	return cre, err
 }
 
-func preDelete(_ context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.DeleteInstanceProfileInput) (bool, error) {
+func (u *updater) preDelete(ctx context.Context, cr *svcapitypes.InstanceProfile, obj *svcsdk.DeleteInstanceProfileInput) (bool, error) {
 	obj.InstanceProfileName = aws.String(meta.GetExternalName(cr))
-	sess, err := session.NewSession()
-	if err != nil {
-		return false, err
-	}
-	svc := iam.New(sess)
-	input := &iam.RemoveRoleFromInstanceProfileInput{
-		InstanceProfileName: aws.String(cr.Name),
+	input := &svcsdk.RemoveRoleFromInstanceProfileInput{
+		InstanceProfileName: aws.String(meta.GetExternalName(cr)),
 		RoleName:            cr.Spec.ForProvider.Role,
 	}
 
-	_, err = svc.RemoveRoleFromInstanceProfile(input)
+	_, err := u.client.RemoveRoleFromInstanceProfileWithContext(ctx, input)
 	return false, err
 }