IAM 자습서: AWS CloudFormation 템플릿을 사용하여 SAML 페더레이션 IAM 역할 생성 - AWS Identity and Access Management

IAM 자습서: AWS CloudFormation 템플릿을 사용하여 SAML 페더레이션 IAM 역할 생성

AWS 계정에 기존 SAML ID 제공업체(idP)가 구성되어 있는 경우, 해당 IdP를 신뢰하는 페더레이션 IAM 역할을 생성할 수 있습니다. 이 자습서에서는 AWS CloudFormation 템플릿을 사용하여 외부 IdP를 통해 인증된 사용자가 수임할 수 있는 SAML 페더레이션 IAM 역할을 생성하는 방법을 보여줍니다.

템플릿은 SAML IdP가 역할을 수임하도록 허용하는 신뢰 정책을 사용하여 페더레이션 IAM 역할을 생성합니다. 외부 IdP에서 인증된 사용자는 이 역할을 수임하여 역할에 연결된 권한을 기준으로 AWS 리소스에 액세스할 수 있습니다.

배포된 리소스는 다음 항목으로 이루어져 있습니다.

  • 기존 SAML IdP를 신뢰하는 페더레이션 IAM 역할.

  • 구성 가능한 관리형 정책 - 역할에 연결하여 특정 권한을 부여할 수 있습니다.

  • 선택적 권한 경계 및 세션 지속 시간 설정.

사전 조건

이 자습서에서는 다음을 이미 완료했다고 가정합니다.

  • AWS 계정에 구성된 기존 SAML IdP. 아직 없는 경우 IAM 자습서: AWS CloudFormation 템플릿을 사용하여 SAML ID 제공업체(idP) 생성 자습서를 사용하여 생성할 수 있습니다.

  • 스택을 생성할 때 파라미터로 지정해야 하는 SAML IdP의 ARN입니다.

  • 이 자습서에서 IdP의 SAML 메타데이터 XML 파일의 형식을 지정하는 데 사용되는 Python 명령을 실행할 수 있도록 로컬 시스템에 설치된 Python 3.6 이상 버전.

AWS CloudFormation을 사용하여 SAML 페더레이션 역할 생성

SAML 페더레이션 역할을 생성하려면 CloudFormation 템플릿을 생성하고 이를 사용하여 역할이 포함된 스택을 생성합니다.

템플릿 생성

우선 CloudFormation 템플릿을 만듭니다.

  1. 템플릿 섹션에서 JSON 또는 YAML 탭의 복사 아이콘을 클릭하여 템플릿 콘텐츠를 복사합니다.

  2. 템플릿 콘텐츠를 새 파일에 붙여 넣습니다.

  3. 파일을 로컬에 저장합니다.

스택 생성

다음으로, 저장한 템플릿을 사용하여 CloudFormation 스택을 프로비저닝합니다.

  1. AWS CloudFormation 콘솔(https://console.aws.amazon.com/cloudformation)을 엽니다.

  2. 스택 페이지의 스택 생성에서 새 리소스 사용(표준)을 선택합니다.

  3. 템플릿을 지정합니다.

    1. 사전 조건에서 기존 템플릿 선택을 선택합니다.

    2. 템플릿 지정에서 템플릿 파일 업로드를 선택합니다.

    3. 파일 선택을 선택하고 템플릿 파일로 이동한 후 해당 파일을 선택합니다.

    4. 다음을 선택합니다.

  4. 다음과 같은 스택 세부 정보를 지정합니다.

    1. 스택 이름을 입력합니다.

    2. SAMLProviderARN의 경우 기존 SAML IdP의 ARN을 입력합니다. 이는 arn:aws:iam::123456789012:saml-provider/YourProviderName 형식이어야 합니다.

      예시: arn:aws:iam::123456789012:saml-provider/CompanyIdP

      참고

      IAM 자습서: AWS CloudFormation 템플릿을 사용하여 SAML ID 제공업체(idP) 생성 자습서를 사용하여 SAML IdP를 생성한 경우, 해당 CloudFormation 스택의 출력 탭에서 제공업체 ARN을 찾을 수 있습니다.

    3. RoleName의 경우 이 값을 비워 두어 스택 이름을 기반으로 이름을 자동 생성하거나, IAM 역할의 사용자 지정 이름을 입력할 수 있습니다.

      예: SAML-Developer-Access 또는 SAML-ReadOnly-Role

    4. 다른 파라미터의 경우 기본값을 적용하거나, 요구 사항에 따라 직접 입력합니다.

      • RoleSessionDuration - 최대 세션 지속 시간(초)(3,600~43,200, 기본값 7,200)

        예: 14400(4시간)

      • RolePermissionsBoundary - 권한 경계 정책의 선택적 ARN

        예시: arn:aws:iam::123456789012:policy/DeveloperBoundary

      • RolePath - IAM 역할의 경로(기본값은 /)

        예시: /saml-roles/

      • ManagedPolicy1-5 - 연결할 최대 5개의 관리형 정책의 선택적 ARN

        ManagedPolicy1의 예: arn:aws:iam::aws:policy/ReadOnlyAccess

        ManagedPolicy2의 예: arn:aws:iam::123456789012:policy/CustomPolicy

    5. 다음을 선택합니다.

  5. 스택 옵션을 구성합니다.

    1. 스택 실패 옵션에서 새로 생성된 모든 리소스 삭제를 선택합니다.

      참고

      이 옵션을 선택하면 스택 생성에 실패하더라도 삭제 정책에서 보존하도록 지정하는 리소스에 대해서는 요금이 청구되지 않습니다.

    2. 모든 기타 기본값을 적용합니다.

    3. 기능에서 CloudFormation이 계정에 IAM 리소스를 생성할 수 있음을 승인하는 확인란을 선택합니다.

    4. 다음을 선택합니다.

  6. 스택 세부 정보를 검토하고 제출을 선택합니다.

AWS CloudFormation이 스택을 생성합니다. 스택 생성이 완료되면 스택 리소스를 사용할 준비가 된 것입니다. 스택 세부 정보 페이지의 리소스 탭을 사용하여 계정에 프로비저닝된 리소스를 볼 수 있습니다.

스택은 출력 탭에서 볼 수 있는 다음과 같은 값을 출력합니다.

  • RoleARN: 생성된 IAM 역할의 ARN(예: arn:aws:iam::123456789012:role/SAML-Developer-Access 또는 자동 생성된 이름을 사용하는 경우 arn:aws:iam::123456789012:role/stack-name-a1b2c3d4).

역할 수임을 위해 적절한 SAML 속성을 전송할 수 있도록 IdP를 구성할 경우 이러한 역할 ARN이 필요합니다.

SAML 페더레이션 역할 테스트

SAML 페더레이션 역할이 생성되면 해당 역할의 구성을 확인하고 페더레이션 설정을 테스트할 수 있습니다.

  1. https://console.aws.amazon.com/iam/에서 IAM 콘솔을 엽니다.

  2. 탐색 창에서 역할을 선택합니다.

  3. 새로 생성된 페더레이션 역할을 찾아 선택합니다.

    사용자 지정 역할 이름을 제공한 경우, 해당 이름을 찾습니다. RoleName 파라미터를 비워 둔 경우, 역할은 스택 이름과 고유 식별자를 기반으로 자동 생성된 이름을 갖게 됩니다.

  4. 신뢰 관계 탭을 선택하여 신뢰 정책을 검토할 수 있습니다.

    신뢰 정책에는 SAML IdP를 신뢰하여 이 역할을 수임할 수 있도록 하며, SAML 대상(SAML:aud)이 https://signin.aws.amazon.com/saml과 일치해야 한다는 조건이 포함된다는 내용이 표시되어야 합니다.

  5. 권한 탭에서 연결된 정책을 검토합니다.

    생성하는 동안 역할에 연결된 모든 관리형 정책을 볼 수 있습니다.

  6. 역할 요약 페이지에 표시된 역할 ARN을 기록합니다.

    사용자가 이 역할을 수임할 수 있도록 외부 IdP를 구성하려면 이 ARN이 필요합니다.

이제 SAML 페더레이션 역할을 사용할 준비가 되었습니다. SAML 어설션에 이 역할의 ARN을 포함하도록 외부 IdP를 구성하면 인증된 사용자가 이 역할을 수임하여 AWS 리소스에 액세스할 수 있습니다.

정리: 리소스 삭제

마지막 단계로, 스택을 삭제하고 해당 스택에 포함된 리소스를 삭제합니다.

  1. AWS CloudFormation 콘솔을 엽니다.

  2. 스택 페이지에서 템플릿을 통해 생성한 스택을 선택하고 삭제를 선택한 다음, 삭제를 확인합니다.

    CloudFormation은 스택 및 해당 스택에 포함된 모든 리소스의 삭제를 시작합니다.

CloudFormation 템플릿 세부 정보

리소스

이 자습서에서 AWS CloudFormation 템플릿은 계정에 다음과 같은 리소스를 생성합니다.

  • AWS::IAM::Role: SAML IdP를 통해 인증된 사용자가 수임할 수 있는 페더레이션 IAM 역할입니다.

구성

템플릿에는 다음과 같은 구성 가능한 파라미터가 포함되어 있습니다.

  • RoleName - IAM 역할의 이름(자동 생성된 이름의 경우 비워둠)

  • SAMLProviderARN - SAML IdP의 ARN(필수)

  • RoleSessionDuration - 최대 세션 지속 시간(초)(3,600~43,200, 기본값 7,200)

  • RolePermissionsBoundary - 권한 경계 정책의 선택적 ARN

  • RolePath - IAM 역할의 경로(기본값은 /)

  • ManagedPolicy1-5 - 연결할 최대 5개의 관리형 정책의 선택적 ARN

CloudFormation 템플릿

아래의 JSON 또는 YAML 코드를 별도의 파일로 저장하여 이 자습서의 CloudFormation 템플릿으로 사용하세요.

JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "[AWSDocs] IAM: tutorial_saml-federated-role", "Parameters": { "RoleName": { "Type": "String", "Description": "Name of the IAM Role (leave empty for auto-generated name like '{StackName}-{UniqueId}')", "Default": "", "AllowedPattern": "^$|^[\\w+=,.@-]{1,64}$", "ConstraintDescription": "Must be empty or 1-64 characters and can contain alphanumeric characters and +=,.@-" }, "SAMLProviderARN": { "Type": "String", "Description": "ARN of the SAML Identity Provider", "AllowedPattern": "^arn:aws:iam::\\d{12}:saml-provider/[a-zA-Z0-9._-]+$", "ConstraintDescription": "Must be a valid SAML provider ARN" }, "RoleSessionDuration": { "Type": "Number", "Description": "The maximum session duration (in seconds) that you want to set for the specified role (3600-43200)", "MinValue": 3600, "MaxValue": 43200, "Default": 7200 }, "RolePermissionsBoundary": { "Type": "String", "Description": "Optional ARN of the permissions boundary policy (leave empty for none)", "Default": "" }, "RolePath": { "Type": "String", "Description": "Path for the IAM role (must start and end with /)", "Default": "/", "AllowedPattern": "^\/.*\/$|^\/$", "ConstraintDescription": "Role path must start and end with forward slash (/)" }, "RoleManagedPolicy1": { "Type": "String", "Description": "Optional managed policy ARN 1", "Default": "" }, "RoleManagedPolicy2": { "Type": "String", "Description": "Optional managed policy ARN 2", "Default": "" }, "RoleManagedPolicy3": { "Type": "String", "Description": "Optional managed policy ARN 3", "Default": "" }, "RoleManagedPolicy4": { "Type": "String", "Description": "Optional managed policy ARN 4", "Default": "" }, "RoleManagedPolicy5": { "Type": "String", "Description": "Optional managed policy ARN 5", "Default": "" } }, "Conditions": { "HasCustomRoleName": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleName"}, ""]}]}, "HasPermissionsBoundary": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RolePermissionsBoundary"}, ""]}]}, "HasPolicy1": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy1"}, ""]}]}, "HasPolicy2": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy2"}, ""]}]}, "HasPolicy3": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy3"}, ""]}]}, "HasPolicy4": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy4"}, ""]}]}, "HasPolicy5": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy5"}, ""]}]} }, "Resources": { "SAMLFederatedRole": { "Type": "AWS::IAM::Role", "Properties": { "RoleName": {"Fn::If": ["HasCustomRoleName", {"Ref": "RoleName"}, {"Ref": "AWS::NoValue"}]}, "Description": "IAM role with SAML provider trust", "MaxSessionDuration": {"Ref": "RoleSessionDuration"}, "PermissionsBoundary": {"Fn::If": ["HasPermissionsBoundary", {"Ref": "RolePermissionsBoundary"}, {"Ref": "AWS::NoValue"}]}, "Path": {"Ref": "RolePath"}, "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": {"Ref": "SAMLProviderARN"} }, "Action": "sts:AssumeRoleWithSAML", "Condition": { "StringEquals": { "SAML:aud": "https://signin.aws.amazon.com/saml" } } } ] }, "ManagedPolicyArns": { "Fn::Split": [ ",", { "Fn::Join": [ ",", [ {"Fn::If": ["HasPolicy1", {"Ref": "RoleManagedPolicy1"}, {"Ref": "AWS::NoValue"}]}, {"Fn::If": ["HasPolicy2", {"Ref": "RoleManagedPolicy2"}, {"Ref": "AWS::NoValue"}]}, {"Fn::If": ["HasPolicy3", {"Ref": "RoleManagedPolicy3"}, {"Ref": "AWS::NoValue"}]}, {"Fn::If": ["HasPolicy4", {"Ref": "RoleManagedPolicy4"}, {"Ref": "AWS::NoValue"}]}, {"Fn::If": ["HasPolicy5", {"Ref": "RoleManagedPolicy5"}, {"Ref": "AWS::NoValue"}]} ] ] } ] } } } }, "Outputs": { "RoleARN": { "Description": "ARN of the created IAM Role", "Value": {"Fn::GetAtt": ["SAMLFederatedRole", "Arn"]}, "Export": { "Name": {"Fn::Sub": "${AWS::StackName}-RoleARN"} } } } }
YAML
AWSTemplateFormatVersion: '2010-09-09' Description: '[AWSDocs] IAM: tutorial_saml-federated-role' Parameters: RoleName: Type: String Description: 'Name of the IAM Role (leave empty for auto-generated name like ''{StackName}-{UniqueId}'')' Default: "" AllowedPattern: '^$|^[\w+=,.@-]{1,64}$' ConstraintDescription: 'Must be empty or 1-64 characters and can contain alphanumeric characters and +=,.@-' SAMLProviderARN: Type: String Description: 'ARN of the SAML Identity Provider' AllowedPattern: '^arn:aws:iam::\d{12}:saml-provider/[a-zA-Z0-9._-]+$' ConstraintDescription: 'Must be a valid SAML provider ARN' RoleSessionDuration: Type: Number Description: 'The maximum session duration (in seconds) that you want to set for the specified role (3600-43200)' MinValue: 3600 MaxValue: 43200 Default: 7200 RolePermissionsBoundary: Type: String Description: Optional ARN of the permissions boundary policy (leave empty for none) Default: "" RolePath: Type: String Description: 'Path for the IAM role (must start and end with /)' Default: "/" AllowedPattern: '^\/.*\/$|^\/$' ConstraintDescription: 'Role path must start and end with forward slash (/)' RoleManagedPolicy1: Type: String Description: Optional managed policy ARN 1 Default: "" RoleManagedPolicy2: Type: String Description: Optional managed policy ARN 2 Default: "" RoleManagedPolicy3: Type: String Description: Optional managed policy ARN 3 Default: "" RoleManagedPolicy4: Type: String Description: Optional managed policy ARN 4 Default: "" RoleManagedPolicy5: Type: String Description: Optional managed policy ARN 5 Default: "" Conditions: HasCustomRoleName: !Not [!Equals [!Ref RoleName, ""]] HasPermissionsBoundary: !Not [!Equals [!Ref RolePermissionsBoundary, ""]] HasPolicy1: !Not [!Equals [!Ref RoleManagedPolicy1, ""]] HasPolicy2: !Not [!Equals [!Ref RoleManagedPolicy2, ""]] HasPolicy3: !Not [!Equals [!Ref RoleManagedPolicy3, ""]] HasPolicy4: !Not [!Equals [!Ref RoleManagedPolicy4, ""]] HasPolicy5: !Not [!Equals [!Ref RoleManagedPolicy5, ""]] Resources: SAMLFederatedRole: Type: 'AWS::IAM::Role' Properties: RoleName: !If - HasCustomRoleName - !Ref RoleName - !Ref AWS::NoValue Description: 'IAM role with SAML provider trust' MaxSessionDuration: !Ref RoleSessionDuration PermissionsBoundary: !If - HasPermissionsBoundary - !Ref RolePermissionsBoundary - !Ref AWS::NoValue Path: !Ref RolePath AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Federated: !Ref SAMLProviderARN Action: 'sts:AssumeRoleWithSAML' Condition: StringEquals: 'SAML:aud': 'https://signin.aws.amazon.com/saml' ManagedPolicyArns: !Split - ',' - !Join - ',' - - !If [HasPolicy1, !Ref RoleManagedPolicy1, !Ref 'AWS::NoValue'] - !If [HasPolicy2, !Ref RoleManagedPolicy2, !Ref 'AWS::NoValue'] - !If [HasPolicy3, !Ref RoleManagedPolicy3, !Ref 'AWS::NoValue'] - !If [HasPolicy4, !Ref RoleManagedPolicy4, !Ref 'AWS::NoValue'] - !If [HasPolicy5, !Ref RoleManagedPolicy5, !Ref 'AWS::NoValue'] Outputs: RoleARN: Description: 'ARN of the created IAM Role' Value: !GetAtt SAMLFederatedRole.Arn Export: Name: !Sub '${AWS::StackName}-RoleARN'