IAM 자습서: CloudFormation 템플릿을 사용하여 SAML ID 제공업체(idP) 생성 - AWS Identity and Access Management

IAM 자습서: CloudFormation 템플릿을 사용하여 SAML ID 제공업체(idP) 생성

AWS 계정에 대한 SAML 페더레이션을 설정하려면 SAML ID 제공업체(idP)를 생성해야 합니다. 이 자습서에서는 CloudFormation 템플릿을 사용하여 AWS와 외부 IdP 간에 신뢰를 설정하는 SAML IdP를 생성하는 방법을 보여줍니다.

이 템플릿은 IdP의 메타데이터 문서로 구성된 SAML IdP를 생성합니다. 그러면 페더레이션 IAM 역할이 이 IdP를 참조하여 외부 IdP의 인증된 사용자가 AWS 리소스에 액세스할 수 있도록 허용합니다.

배포된 리소스는 IdP의 메타데이터 문서와 선택적 암호화 설정으로 구성된 SAML IdP로 이루어져 있습니다.

사전 조건

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

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

  • XML 파일로 저장된 외부 IdP의 SAML 메타데이터 문서.

CloudFormation을 사용하여 SAML IdP 생성

SAML IdP를 생성하려면 CloudFormation 템플릿을 생성하고 이를 사용하여 IdP 리소스가 포함된 스택을 생성합니다.

템플릿 생성

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

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

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

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

스택 생성

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

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

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

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

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

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

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

    4. 다음을 선택합니다.

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

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

    2. IdentityProviderName의 경우 이 값을 비워 두어 스택 이름을 기반으로 이름을 자동 생성하거나, SAML IdP의 사용자 지정 이름을 입력할 수 있습니다. 사용자 지정 이름에는 영숫자, 마침표, 밑줄, 하이픈만 포함할 수 있습니다.

    3. IdentityProviderSAMLMetadataDocument의 경우 이 필드에 붙여 넣기 전에 SAML 메타데이터 XML 파일의 형식을 한 줄로 지정해야 합니다. 이렇게 해야 하는 이유는 CloudFormation 콘솔에서 콘솔 파라미터를 전달할 때 XML 콘텐츠의 형식을 한 줄로 지정해야 하기 때문입니다.

      아래의 Python 명령을 사용하여 XML 파일의 형식을 다시 지정합니다.

      python3 -c "import sys, re; content=open(sys.argv[1]).read(); print(re.sub(r'>\s+<', '><', content.replace('\n', '').replace('\r', '').strip()))" saml-metadata.xml
      참고

      IdP의 SAML 메타데이터 문서는 콘솔 파라미터 입력을 위해 한 줄로 형식을 지정해야 합니다. Python 명령은 줄 바꿈과 추가 공백을 제거하여 모든 원본 콘텐츠와 구조를 그대로 유지하면서 필요한 형식을 생성합니다.

      Python 명령에서 출력을 복사한 후 이를 IdentityProviderSAMLMetadataDocument 필드에 붙여 넣습니다.

      형식이 지정된 SAML 메타데이터 문서의 예시(간략화함):

      <?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://portal.sso.example.com/saml/assertion/CompanyIdP"><md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiIMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV...</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://portal.sso.example.com/saml/logout/CompanyIdP"/><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://portal.sso.example.com/saml/assertion/CompanyIdP"/></md:IDPSSODescriptor></md:EntityDescriptor>
    4. 다른 파라미터의 경우 기본값을 적용하거나, 요구 사항에 따라 직접 입력합니다.

      • IdentityProviderAddPrivateKey - SAML 어설션의 암호 해독을 위한 선택적 프라이빗 키

      • IdentityProviderAssertionEncryptionMode - 선택 사항, SAML 어설션에 대한 암호화 모드 설정(허용됨, 필수 또는 비어 있음)

    5. 다음을 선택합니다.

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

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

      참고

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

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

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

    4. 다음을 선택합니다.

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

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

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

  • ProviderARN: 생성된 SAML IdP의 ARN(예: arn:aws:iam::123456789012:saml-provider/CompanyIdP). 이 제공업체를 신뢰하는 역할을 생성할 경우 이 ARN이 필요합니다.

  • ProviderName: 생성된 SAML IdP의 이름(예: 사용자 지정 이름을 지정한 경우 CompanyIdP, 또는 기본 이름을 사용한 경우 my-saml-stack-saml-provider).

이러한 출력도 내보내므로, Fn::ImportValue 함수를 사용하여 이를 다른 CloudFormation 스택에서 가져올 수 있습니다.

SAML IdP 확인

SAML IdP가 생성되면 구성을 확인하고 페더레이션 역할과 함께 사용할 ARN을 기록할 수 있습니다.

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

  2. 탐색 창에서 [자격 증명 공급자(Identity providers)]를 선택합니다.

    새로 생성된 SAML IdP가 목록에 표시됩니다.

  3. 세부 정보를 보려면 IdP 이름을 선택합니다.

    IdP 세부 정보 페이지에서 SAML 메타데이터 문서 및 기타 구성 세부 정보를 볼 수 있습니다.

  4. 세부 정보 페이지에 표시된 공급자 ARN을 기록해 둡니다.

    이 IdP를 신뢰하는 페더레이션 IAM 역할을 생성할 경우 이 ARN이 필요합니다.

  5. 메타데이터 문서를 검토하여 외부 IdP에서 제공한 것과 일치하는지 확인합니다.

이제 SAML IdP를 페더레이션 IAM 역할에서 사용할 준비가 되었습니다. 이 IdP를 신뢰하는 역할을 생성하면 외부 IdP의 인증된 사용자가 이러한 역할을 수임하고 AWS 리소스에 액세스할 수 있습니다.

정리: 리소스 삭제

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

  1. CloudFormation 콘솔을 엽니다.

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

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

CloudFormation 템플릿 세부 정보

리소스

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

AWS::IAM::SAMLProvider: AWS와 외부 IdP 간에 신뢰를 설정하는 SAML IdP입니다.

구성

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

  • IdentityProviderName - SAML IdP의 이름(자동 생성된 이름의 경우 비워둠)

    예: CompanyIdP 또는 EnterpriseSSO

  • IdentityProviderSAMLMetadataDocument - 외부 IdP의 SAML 메타데이터 문서(한 줄 형식)

  • IdentityProviderAddPrivateKey - SAML 어설션의 암호 해독을 위한 선택적 프라이빗 키

  • IdentityProviderAssertionEncryptionMode - 선택 사항, SAML 어설션에 대한 암호화 모드 설정

CloudFormation 템플릿

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

JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "[AWSDocs] IAM: tutorial_saml-idp", "Parameters": { "IdentityProviderName": { "Type": "String", "Description": "Name of the SAML Identity Provider (leave empty for auto-generated name like '{StackName}-{UniqueId}')", "Default": "", "AllowedPattern": "^$|^[a-zA-Z0-9._-]+$", "ConstraintDescription": "Must be empty or contain only alphanumeric characters, periods, underscores, and hyphens" }, "IdentityProviderSAMLMetadataDocument": { "Type": "String", "Description": "SAML metadata document from identity provider" }, "IdentityProviderAddPrivateKey": { "Type": "String", "Description": "Optional private key for decrypting SAML assertions. The private key must be a .pem file that uses AES-GCM or AES-CBC encryption algorithm to decrypt SAML assertions.", "Default": "" }, "IdentityProviderAssertionEncryptionMode": { "Type": "String", "Description": "Optional, sets encryption mode for SAML assertions", "Default": "", "AllowedValues": ["", "Allowed", "Required"] } }, "Conditions": { "HasPrivateKey": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderAddPrivateKey"}, ""]}]}, "HasEncryptionMode": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderAssertionEncryptionMode"}, ""]}]}, "HasCustomName": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderName"}, ""]}]} }, "Resources": { "SAMLProvider": { "Type": "AWS::IAM::SAMLProvider", "Properties": { "Name": {"Fn::If": ["HasCustomName", {"Ref": "IdentityProviderName"}, {"Ref": "AWS::NoValue"}]}, "SamlMetadataDocument": {"Ref": "IdentityProviderSAMLMetadataDocument"}, "Tags": [ { "Key": "Name", "Value": {"Fn::If": ["HasCustomName", {"Ref": "IdentityProviderName"}, {"Fn::Sub": "${AWS::StackName}-saml-provider"}]} } ], "AddPrivateKey": {"Fn::If": ["HasPrivateKey", {"Ref": "IdentityProviderAddPrivateKey"}, {"Ref": "AWS::NoValue"}]}, "AssertionEncryptionMode": {"Fn::If": ["HasEncryptionMode", {"Ref": "IdentityProviderAssertionEncryptionMode"}, {"Ref": "AWS::NoValue"}]} } } }, "Outputs": { "ProviderARN": { "Description": "ARN of the created SAML Identity Provider", "Value": {"Ref": "SAMLProvider"}, "Export": { "Name": {"Fn::Sub": "${AWS::StackName}-ProviderARN"} } }, "ProviderName": { "Description": "Name of the SAML Identity Provider", "Value": {"Fn::If": ["HasCustomName", {"Ref": "IdentityProviderName"}, {"Fn::Sub": "${AWS::StackName}-saml-provider"}]}, "Export": { "Name": {"Fn::Sub": "${AWS::StackName}-ProviderName"} } } } }
YAML
AWSTemplateFormatVersion: '2010-09-09' Description: '[AWSDocs] IAM: tutorial_saml-idp' Parameters: IdentityProviderName: Type: String Description: Name of the SAML Identity Provider (leave empty for auto-generated name like '{StackName}-{UniqueId}') Default: "" AllowedPattern: '^$|^[a-zA-Z0-9._-]+$' ConstraintDescription: 'Must be empty or contain only alphanumeric characters, periods, underscores, and hyphens' IdentityProviderSAMLMetadataDocument: Type: String Description: SAML metadata document from identity provider IdentityProviderAddPrivateKey: Type: String Description: Optional private key for decrypting SAML assertions. The private key must be a .pem file that uses AES-GCM or AES-CBC encryption algorithm to decrypt SAML assertions. Default: "" IdentityProviderAssertionEncryptionMode: Type: String Description: Optional, sets encryption mode for SAML assertions Default: "" AllowedValues: - "" - "Allowed" - "Required" Conditions: HasPrivateKey: !Not [!Equals [!Ref IdentityProviderAddPrivateKey, ""]] HasEncryptionMode: !Not [!Equals [!Ref IdentityProviderAssertionEncryptionMode, ""]] HasCustomName: !Not [!Equals [!Ref IdentityProviderName, ""]] Resources: SAMLProvider: Type: 'AWS::IAM::SAMLProvider' Properties: Name: !If - HasCustomName - !Ref IdentityProviderName - !Ref AWS::NoValue SamlMetadataDocument: !Ref IdentityProviderSAMLMetadataDocument Tags: - Key: Name Value: !If - HasCustomName - !Ref IdentityProviderName - !Sub '${AWS::StackName}-saml-provider' AddPrivateKey: !If - HasPrivateKey - !Ref IdentityProviderAddPrivateKey - !Ref AWS::NoValue AssertionEncryptionMode: !If - HasEncryptionMode - !Ref IdentityProviderAssertionEncryptionMode - !Ref AWS::NoValue Outputs: ProviderARN: Description: 'ARN of the created SAML Identity Provider' Value: !Ref SAMLProvider Export: Name: !Sub '${AWS::StackName}-ProviderARN' ProviderName: Description: 'Name of the SAML Identity Provider' Value: !If - HasCustomName - !Ref IdentityProviderName - !Sub '${AWS::StackName}-saml-provider' Export: Name: !Sub '${AWS::StackName}-ProviderName'